package com.uzai.console.service.tiktok.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.uzai.common.dto.device.*;
import com.uzai.common.enums.*;
import com.uzai.common.exception.BusinessException;
import com.uzai.common.msg.MsgDto;
import com.uzai.common.result.ResponseCode;
import com.uzai.common.utils.Math;
import com.uzai.console.common.UzaiRespVo;
import com.uzai.console.common.utils.DateUtil;
import com.uzai.console.common.utils.Tools;
import com.uzai.console.config.UzaiConsoleSysConfig;
import com.uzai.console.constant.Const;
import com.uzai.console.dto.alipaydetail.AlipayDetailCreateDto;
import com.uzai.console.dto.device.deviceauth.DeviceAuthQuery;
import com.uzai.console.dto.module.deviceproduct.DeviceProductQuery;
import com.uzai.console.dto.rocketmq.androidapp.UpdateAndroidAppDto;
import com.uzai.console.dto.rocketmq.devicewechatinfo.CloseClientAppDto;
import com.uzai.console.dto.rocketmq.devicewechatinfo.UpdateClientAppDto;
import com.uzai.console.dto.tiktok.devicetiktokinfo.*;
import com.uzai.console.dto.wechatprivate.devicewechatinfo.*;
import com.uzai.console.entity.*;
import com.uzai.console.enums.*;
import com.uzai.console.mapper.*;
import com.uzai.console.service.alipaydetail.AlipayDetailService;
import com.uzai.console.service.deviceauth.DeviceAuthService;
import com.uzai.console.service.feign.UzaiImClientFeignService;
import com.uzai.console.service.rocketmq.NoticeMsgPushProducerService;
import com.uzai.console.service.tiktok.DeviceTiktokInfoService;
import com.uzai.console.vo.alarm.alarmrule.AlarmRuleInfoVo;
import com.uzai.console.vo.alipaydetail.businessinfo.DeviceAddBusinessInfo;
import com.uzai.console.vo.alipaydetail.businessinfo.DeviceAuthBusinessInfo;
import com.uzai.console.vo.deviceauth.DeviceAuthVo;
import com.uzai.console.vo.deviceproduct.DeviceProductVo;
import com.uzai.console.vo.tiktok.devicetiktokinfo.DeviceTiktokInfoAddVo;
import com.uzai.console.vo.tiktok.devicetiktokinfo.DeviceTiktokInfoVo;
import com.uzai.console.vo.wechatprivate.devicewechatinfo.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * 机器人
 * @author liuqi
 * @date 2021年08月19日 16:50
 */
@Service
public class DeviceTiktokInfoServiceImpl implements DeviceTiktokInfoService {

    Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private DeviceTiktokInfoMapper deviceTiktokInfoMapper;
    @Autowired
    private DeviceGroupMapper deviceGroupMapper;
    @Autowired
    private ConfigPlanMapper configPlanMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private SysPluginMapper sysPluginMapper;
    @Autowired
    private DeviceVersionMapper deviceVersionMapper;
    @Autowired
    private NoticeMsgPushProducerService noticeMsgPushProducerService;
    @Autowired
    private DeviceAuthMapper deviceAuthMapper;
    @Autowired
    private DeviceAuthDetailMapper deviceAuthDetailMapper;
    @Autowired
    private DevicePriceMapper devicePriceMapper;
    @Autowired
    private AlipayDetailService alipayDetailService;
    @Autowired
    private AlipayDetailMapper alipayDetailMapper;
    @Autowired
    private CdkeysMapper cdkeysMapper;
    @Autowired
    private MerchantMapper merchantMapper;
    @Autowired
    private MerAccDetailMapper merAccDetailMapper;
    @Autowired
    private UzaiConsoleSysConfig uzaiConsoleSysConfig;
    @Autowired
    private DeviceProductMapper deviceProductMapper;
    @Autowired
    private AlarmRuleMapper alarmRuleMapper;
    @Autowired
    private CdkeysMobileAppMapper cdkeysMobileAppMapper;
    @Autowired
    private DeviceAuthService deviceAuthService;
    @Autowired
    private UzaiImClientFeignService uzaiImClientFeignService;
    @Autowired
    private WechatUserMapper wechatUserMapper;
    @Autowired
    private TbOrderMapper tbOrderMapper;
    @Autowired
    private JdOrderMapper jdOrderMapper;
    @Autowired
    private PddOrderMapper pddOrderMapper;
    @Autowired
    private VphOrderMapper vphOrderMapper;
    @Autowired
    private MtOrderMapper mtOrderMapper;
    @Autowired
    private DyOrderMapper dyOrderMapper;

    /**
     * 查询抖音设备机器人列表
     * @author liuqi
     * @date 2021/8/13 11:38
     * @param deviceTiktokInfoQuery
     * @return null
     */
    public Page<DeviceTiktokInfoVo> findDeviceTiktokInfoList(DeviceTiktokInfoQuery deviceTiktokInfoQuery){

        //手动处理机器人分页查询-如果是机器人昵称，则按照中文gbk排序
        List<OrderItem> orderItemList = deviceTiktokInfoQuery.getOrderItemList();
        if(orderItemList != null && orderItemList.size() > 0){
            for (OrderItem orderItem :orderItemList){
                if("deviceName".equals(orderItem.getColumn())){
                    orderItem.setColumn(" convert( " + orderItem.getColumn() + " using gbk) ");
                }
            }
        }

        Integer now = DateUtil.getNowTime();

        //新建返回到页面的LIST对象
        List<DeviceTiktokInfoVo> deviceTiktokInfoPageVoList = new ArrayList<>();
        //执行分页查询对象
        Page<DeviceTiktokInfo> page = new Page<>();
        deviceTiktokInfoQuery.convert(page);

        ArrayList<DeviceTiktokInfo> deviceTiktokInfoList =  deviceTiktokInfoMapper.findByList(page, deviceTiktokInfoQuery);
        if(deviceTiktokInfoList != null && deviceTiktokInfoList.size() > 0){
            for (DeviceTiktokInfo deviceTiktokInfo : deviceTiktokInfoList){
                DeviceTiktokInfoVo deviceTiktokInfoPageVo = new DeviceTiktokInfoVo();
                BeanUtils.copyProperties(deviceTiktokInfo, deviceTiktokInfoPageVo);

                //机器人分组
                DeviceGroup deviceGroup = deviceGroupMapper.selectById(deviceTiktokInfo.getGroupId(), deviceTiktokInfo.getMerId());
                if(deviceGroup != null){
                    deviceTiktokInfoPageVo.setGroupName(deviceGroup.getName());
                }
                //获取配置方案信息
                ConfigPlan configPlan = configPlanMapper.selectById(deviceTiktokInfo.getConfigId(), deviceTiktokInfo.getMerId());
                if(configPlan != null){
                    deviceTiktokInfoPageVo.setConfigName(configPlan.getName());
                }

                //是否可以转移授权时间
                boolean transferAuthTimeFlag = false; //默认不可以

                //授权信息
                List<DeviceAuthVo> deviceAuthVoList = new ArrayList<>();
                DeviceAuthQuery deviceAuthQuer = new DeviceAuthQuery();
                deviceAuthQuer.setDeviceId(deviceTiktokInfo.getDeviceId());
                deviceAuthQuer.setDeviceType(DeviceTypeEnum.TIKTOK.getKey());
                List<DeviceAuth> deviceAuthList =  deviceAuthMapper.findByList(deviceAuthQuer);
                if(deviceAuthList != null && deviceAuthList.size() > 0){
                    for (DeviceAuth deviceAuth : deviceAuthList){
                        DeviceAuthVo deviceAuthVo = new DeviceAuthVo();
                        BeanUtils.copyProperties(deviceAuth, deviceAuthVo);
                        DeviceProductKeyEnum deviceProductKeyEnum = DeviceProductKeyEnum.getValue(deviceAuth.getProductCode());
                        if(deviceProductKeyEnum != null){
                            deviceAuthVo.setProductName(deviceProductKeyEnum.getDesc());
                        }
                        //到期时间
                        Integer expiretime = Tools.getInteger(deviceAuthVo.getExpireTime());
                        if(expiretime.intValue() <= now.intValue()){
                            deviceAuthVo.setExpireStatus(0);  //已到期
                        }else if(expiretime.intValue() > now && expiretime.intValue() <= now + 7*24*3600){
                            deviceAuthVo.setExpireStatus(2);  //即将到期
                        }else{
                            deviceAuthVo.setExpireStatus(1);  //未到期
                            transferAuthTimeFlag = true; //只要有未到期的授权产品，就可以转移授权时间
                        }
                        deviceAuthVoList.add(deviceAuthVo);
                    }
                }
                
                //封装授权记录
                deviceTiktokInfoPageVo.setDeviceAuthVoList(deviceAuthVoList);

                //设置是否可以转移授权时间
                if(transferAuthTimeFlag){
                    deviceTiktokInfoPageVo.setTransferAuthTimeFlag(1);
                }else{
                    deviceTiktokInfoPageVo.setTransferAuthTimeFlag(0);
                }
                
                try{
                    //从缓存中获取抖音设备手机端信息
                    Object object_mobile = redisTemplate.opsForValue().get(String.format(RedisCacheKeyEnum.DEVICE_INFO_TIKTOK.getKey(), deviceTiktokInfo.getId()));
                    if(object_mobile != null){
                        DeviceInfoTiktokCacheDto deviceInfoTiktokCacheDto = JSONObject.parseObject(String.valueOf(object_mobile), DeviceInfoTiktokCacheDto.class);
                        //手机端抖音设备信息不为空
                        if(deviceInfoTiktokCacheDto != null){
                            //客户端版本号
                            deviceTiktokInfoPageVo.setMobileClientVersion(deviceInfoTiktokCacheDto.getClientVersion());
                            deviceTiktokInfoPageVo.setUpdateMobileClientVersion(0); //默认版本相同，不更新
                            //获取机器人最新移动端版本
                            //从缓存中获取版本移动端版本信息
                            Object object_mobile_version = redisTemplate.opsForValue().get(RedisCacheKeyEnum.MOBILE_APP_UPDATE_INFO.getKey());
                            if(object_mobile_version != null){
                                JSONObject jsonObject = JSONObject.parseObject(object_mobile_version.toString());
                                if(jsonObject != null){
                                    //软件版本号
                                    Integer verNumber = Tools.getInteger(jsonObject.getInteger("verNumber"));
                                    //软件版本名称
                                    String version = Tools.getStr(jsonObject.getString("version"));
                                    //包名称
                                    String packageName = Tools.getStr(jsonObject.getString("packageName"));
                                    //软件包URL地址
                                    String packageUrl = Tools.getStr(jsonObject.getString("packageUrl"));
                                    //版本号不相等，有更新
                                    if(!version.equals(deviceInfoTiktokCacheDto.getClientVersion())){
                                        //deviceTiktokInfoPageVo.setUpdateMobileClientVersion(1); //版本号不相同，需要更新
                                    }
                                }
                            }

                            //移动抖音版本号
                            deviceTiktokInfoPageVo.setMobileTiktokVersion(deviceInfoTiktokCacheDto.getWxVersion());
                            //是否在线，默认为离线
                            deviceTiktokInfoPageVo.setMobileOnLine(0);
                            //获取最新心跳时间
                            Integer lastHeartBeatTime = deviceInfoTiktokCacheDto.getLastHeartBeatTime();
                            if(lastHeartBeatTime != null){
                                //判断在线（少于5分钟表示在线）
                                if(DateUtil.getNowTime() - lastHeartBeatTime  < Const.Device.HEART_BEAT_OFF_LINE_TIME){
                                    deviceTiktokInfoPageVo.setMobileOnLine(1); //在线
                                }
                            }

                            //软件到期日期
                            //deviceTiktokInfoPageVo.setMobileExpireTime(deviceInfoTiktokCacheDto.getExpireTime());
                            //是否处理消息
                            //deviceTiktokInfoPageVo.setMobileMsgHandler(deviceInfoTiktokCacheDto.getMsgHandler());

                            //手机剩余电量百分比
                            deviceTiktokInfoPageVo.setBatteryLevel(Tools.getInteger(deviceInfoTiktokCacheDto.getBatteryLevel()));
                            //手机外部存储（sdcard）剩余空间字节数
                            Long sdCardFree = Tools.getLong(deviceInfoTiktokCacheDto.getSdCardFree());
                            deviceTiktokInfoPageVo.setSdCardFree(Math.round(sdCardFree/1024d/1024d,2));
                        }
                    }
                }catch (Exception e){

                }

                //封装报警规则信息
                if(deviceTiktokInfo.getAlarmRuleId() != null){
                    AlarmRule alarmRule = alarmRuleMapper.selectById(deviceTiktokInfo.getAlarmRuleId(), deviceTiktokInfo.getMerId());
                    if(alarmRule != null){
                        AlarmRuleInfoVo alarmRuleInfoVo = new AlarmRuleInfoVo();
                        BeanUtils.copyProperties(alarmRule, alarmRuleInfoVo);
                        deviceTiktokInfoPageVo.setAlarmRuleInfoVo(alarmRuleInfoVo);
                    }
                }

                deviceTiktokInfoPageVoList.add(deviceTiktokInfoPageVo);
            }
        }

        //返回到页面分页对象
        Page<DeviceTiktokInfoVo> pageVo = new Page<>();
        BeanUtils.copyProperties(page, pageVo);
        pageVo.setRecords(deviceTiktokInfoPageVoList);
        return pageVo;
    }

    /**
     * 查询机器人详情
     * @author liuqi
     * @date 2021/8/13 11:38
     * @param deviceTiktokInfoIdDto
     * @return DeviceTiktokInfoVo
     */
    public DeviceTiktokInfoVo findDeviceTiktokInfoInfo(DeviceTiktokInfoIdDto deviceTiktokInfoIdDto){
        if(deviceTiktokInfoIdDto.getId() == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "id不能为空");
        }
        DeviceTiktokInfo deviceTiktokInfo = deviceTiktokInfoMapper.selectById(deviceTiktokInfoIdDto.getId(), deviceTiktokInfoIdDto.getMerId());

        if(deviceTiktokInfo == null ){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该机器人不存在");
        }
        DeviceTiktokInfoVo deviceTiktokInfoPageVo = new DeviceTiktokInfoVo();

        BeanUtils.copyProperties(deviceTiktokInfo, deviceTiktokInfoPageVo);

        return deviceTiktokInfoPageVo;
    }

    /**
     * 添加机器人信息，创建订单
     * @author liuqi
     * @date 2021/8/25 11:38
     * @param deviceTiktokInfoAddDto
     */
    @Transactional
    public void addDeviceTiktokInfo(DeviceTiktokInfoAddDto deviceTiktokInfoAddDto){

        //查询账号信息
        Merchant merchant = merchantMapper.selectById(deviceTiktokInfoAddDto.getMerId());
        if(merchant == null) {
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该运营商不存在");
        }

        DeviceTiktokInfoAddVo deviceTiktokInfoAddVo = new DeviceTiktokInfoAddVo();
        String trandeNo = Tools.getCurrentTimeByFormat("yyyyMMdd") + IdWorker.getIdStr();
        Integer now = DateUtil.getNowTime();
        Integer expired_time = now;
        Long merId = deviceTiktokInfoAddDto.getMerId();

        //机器人类型id
        Integer deviceTypeId = DeviceTypeEnum.TIKTOK.getId();
        //机器人类型key
        String deviceTypeKey = DeviceTypeEnum.TIKTOK.getKey();

        //机器人wxid
        String deviceId = deviceTiktokInfoAddDto.getDeviceId();
        if(StringUtils.isBlank(deviceId)){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入机器人wxid");
        }

        //选择该运营商默认配置方案
//        ConfigPlan configPlan = configPlanMapper.selectByIsDefault(deviceTiktokInfoAddDto.getMerId(), deviceTypeKey);
//        if(configPlan == null){
//            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该运营商没有默认的配置方案");
//        }

        //查询整个数据库当中正在使用的该微信id
        DeviceTiktokInfo deviceTiktokInfo = deviceTiktokInfoMapper.selectByDeviceId(deviceId);
        //有在使用的机器人
        if(deviceTiktokInfo != null){
            //该机器人不属于自己运营商，则提示错误
            if(deviceTiktokInfo.getMerId().longValue() != deviceTiktokInfoAddDto.getMerId().longValue()){
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该抖音设备ID已经被其他运营商使用");
            }
        }

        //目前抖音机器人只能试用发单功能
        DeviceProduct deviceProduct_add = deviceProductMapper.selectByCode(TiktokDeviceProductEnum.FD.getValue());
        if(deviceProduct_add == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "系统还未配置全包套餐");
        }

        //List<String> productCodeList = JSONObject.parseArray(deviceProduct_add.getCodes(), String.class);
        //从枚举中获取关联的产品
        TiktokDeviceProductEnum deviceProductEnum = TiktokDeviceProductEnum.getValue(deviceProduct_add.getCode());
        List<String> productCodeList = JSONObject.parseArray(deviceProductEnum.getCodes(), String.class);
        if(productCodeList == null || productCodeList.size() == 0){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "系统抖音设备产品配置有问题");
        }

        //是否新增机器人
        if(deviceTiktokInfo == null ) {//机器人为空，未还添加，则先添加机器人，默认配置方案
            //添加机器人
            deviceTiktokInfo = new DeviceTiktokInfo();
            deviceTiktokInfo.setId(IdWorker.getId());
            deviceTiktokInfo.setMerId(deviceTiktokInfoAddDto.getMerId());
            deviceTiktokInfo.setDeviceId(deviceTiktokInfoAddDto.getDeviceId());
            deviceTiktokInfo.setConfigId(0L); //目前还未支持配置方案
            deviceTiktokInfo.setRecvmsgType(DeviceTypeEnum.TIKTOK.getId());//抖音
            deviceTiktokInfo.setDelStatus(DeleteStatusEnum.VALID.getId());//有效
            deviceTiktokInfo.setCreateTime(now);
            deviceTiktokInfo.setUpdateTime(now);
            //添加机器人
            deviceTiktokInfoMapper.insert(deviceTiktokInfo);

            //选择该运营商默认配置方案，需要将配置方案当中的其他信息添加到Redis当中得 设备消息回复配置信息
//            if (configPlan.getOtherId() != null) {
//                SysPlugin sysPlugin = sysPluginMapper.selectById(configPlan.getOtherId(), deviceTiktokInfoAddDto.getMerId());
//                if (sysPlugin != null) {
//                    redisTemplate.opsForValue().set(String.format(RedisCacheKeyEnum.DEVICE_MSG_CONFIG.getKey(), deviceTiktokInfo.getId()), sysPlugin.getData());
//                }
//            }
        }

        //封装机器人授权信息
        List<DeviceInfoTiktokCacheDto.DeviceProductAuth> deviceProductAuthList = new ArrayList<>();
        //查询该设备id是否已经授权过，如果没有，则开通试用期授权
        DeviceAuth deviceAuth_last = deviceAuthMapper.selectLastAuthByDeviceId(deviceId);
        if(deviceAuth_last == null){//未开通过授权，则开通试用期权限
            expired_time = now + 5 * 24 * 3600;
            //新增加时，目前只支持发单功能试用
            for (String productCode : productCodeList) {
                //机器人redis缓存信息-产品授权
                DeviceInfoTiktokCacheDto.DeviceProductAuth deviceProductAuth = new DeviceInfoTiktokCacheDto.DeviceProductAuth();
                deviceProductAuth.setAuthType(DeviceAuthTypeEnum.DAT_FREE.getId().intValue());
                deviceProductAuth.setExpireTime(expired_time);
                deviceProductAuth.setProductCode(productCode);
                deviceProductAuthList.add(deviceProductAuth);

                //封装设备产品授权记录明细
                DeviceAuthDetail deviceAuthDetail = new DeviceAuthDetail();
                deviceAuthDetail.setId(IdWorker.getId());
                deviceAuthDetail.setMerId(merId);
                deviceAuthDetail.setDeviceUniqueId(deviceTiktokInfo.getId());
                deviceAuthDetail.setDeviceId(deviceTiktokInfo.getDeviceId());
                deviceAuthDetail.setDeviceType(deviceTypeKey);
                deviceAuthDetail.setDeviceTypeId(deviceTypeId);
                deviceAuthDetail.setProductCode(productCode);
                deviceAuthDetail.setAuthType(DeviceAuthTypeEnum.DAT_FREE.getId().intValue());
                deviceAuthDetail.setQuantity(0); //试用为0
                deviceAuthDetail.setPayTime(now);
                deviceAuthDetail.setPayType(PaymentTypeEnum.PAY_FREE.getId());
                deviceAuthDetail.setTradeno(trandeNo);
                deviceAuthDetail.setRemark("试用期");
                deviceAuthDetail.setCreateTime(now);
                deviceAuthDetail.setUpdateTime(now);
                deviceAuthDetail.setAmount(0.00);
                deviceAuthDetail.setBeginTime(now);
                deviceAuthDetail.setExpireTime(expired_time);
                //插入授权数据明细
                deviceAuthDetailMapper.insert(deviceAuthDetail);

                //添加机器人授权表
                DeviceAuth deviceAuth = new DeviceAuth();
                deviceAuth.setId(IdWorker.getId());
                deviceAuth.setDeviceId(deviceTiktokInfo.getDeviceId());
                deviceAuth.setDeviceUniqueId(deviceTiktokInfo.getId());
                deviceAuth.setDeviceType(deviceTypeKey);
                deviceAuth.setDeviceTypeId(deviceTypeId);
                deviceAuth.setAuthType(DeviceAuthTypeEnum.DAT_FREE.getId().intValue());
                deviceAuth.setProductCode(productCode);
                //新授权，到期时间从今天开始算
                deviceAuth.setExpireTime(expired_time);
                deviceAuth.setCreateTime(now);
                deviceAuth.setUpdateTime(now);
                deviceAuthMapper.insert(deviceAuth);
            }
        }else{
            //刷新旧授权
            DeviceAuthQuery deviceAuthQuery = new DeviceAuthQuery();
            deviceAuthQuery.setDeviceId(deviceId);
            deviceAuthQuery.setDeviceType(DeviceTypeEnum.TIKTOK.getKey());
            List<DeviceAuth> deviceAuthList = deviceAuthMapper.findByList(deviceAuthQuery);
            if(deviceAuthList != null && deviceAuthList.size() > 0){
                //机器人redis缓存信息-产品授权
                DeviceInfoTiktokCacheDto.DeviceProductAuth deviceProductAuth = new DeviceInfoTiktokCacheDto.DeviceProductAuth();
                for(DeviceAuth deviceAuth : deviceAuthList){
                    deviceProductAuth.setAuthType(deviceAuth.getAuthType());
                    deviceProductAuth.setExpireTime(deviceAuth.getExpireTime());
                    deviceProductAuth.setProductCode(deviceAuth.getProductCode());
                    deviceProductAuthList.add(deviceProductAuth);
                }
            }
        }

        //添加redis缓存-机器人所属运营商
        Merchant device_merchant = new Merchant();
        device_merchant.setId(merchant.getId());
        redisTemplate.opsForValue().set(String.format(RedisCacheKeyEnum.DEVICE_MERCHANT.getKey(), deviceTiktokInfo.getDeviceId()), Tools.getStrEmpty(JSONObject.toJSONString(device_merchant)));
        
        //更新机器人redis
        Object object = redisTemplate.opsForValue().get(String.format(RedisCacheKeyEnum.DEVICE_INFO_TIKTOK.getKey(), deviceTiktokInfo.getId()));
        if(object != null) {//修改运营商信息
            DeviceInfoTiktokCacheDto deviceInfoTiktokCacheDto = JSONObject.parseObject(object.toString(), DeviceInfoTiktokCacheDto.class);
            if(deviceInfoTiktokCacheDto != null){
                deviceInfoTiktokCacheDto.setMerId(merId);
                deviceInfoTiktokCacheDto.setDeviceAuths(deviceProductAuthList);
                //更新移动端机器人redis
                redisTemplate.opsForValue().set(String.format(RedisCacheKeyEnum.DEVICE_INFO_TIKTOK.getKey(), deviceTiktokInfo.getId()), Tools.getStrEmpty(JSONObject.toJSONString(deviceInfoTiktokCacheDto)));
            }
        }else{
            DeviceInfoTiktokCacheDto deviceInfoTiktokCacheDto = new DeviceInfoTiktokCacheDto();
            deviceInfoTiktokCacheDto.setMerId(merId);
            deviceInfoTiktokCacheDto.setDeviceId(deviceId);
            deviceInfoTiktokCacheDto.setDeviceUniqueId(deviceTiktokInfo.getId());
            deviceInfoTiktokCacheDto.setConfigId(deviceTiktokInfo.getConfigId());
            deviceInfoTiktokCacheDto.setDeviceAuths(deviceProductAuthList);
            deviceInfoTiktokCacheDto.setMsgHandler(1); //处理消息
            //更新移动端机器人redis
            redisTemplate.opsForValue().set(String.format(RedisCacheKeyEnum.DEVICE_INFO_TIKTOK.getKey(), deviceTiktokInfo.getId()), Tools.getStrEmpty(JSONObject.toJSONString(deviceInfoTiktokCacheDto)));
        }
    }

    /**
     * 修改机器人信息
     * @author liuqi
     * @date 2021/8/25 11:38
     * @param deviceTiktokInfoDto
     */
    public void updateDeviceTiktokInfo(DeviceTiktokInfoDto deviceTiktokInfoDto){

        if(deviceTiktokInfoDto.getId() == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入id参数");
        }

//        if(deviceTiktokInfoDto.getConfigId() == null){
//            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请选择配置方案");
//        }

        DeviceTiktokInfo deviceTiktokInfo = deviceTiktokInfoMapper.selectById(deviceTiktokInfoDto.getId(), deviceTiktokInfoDto.getMerId());
        if(deviceTiktokInfo == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该机器人不存在");
        }

        Integer now = DateUtil.getNowTime();
        deviceTiktokInfo.setDeviceName(deviceTiktokInfoDto.getDeviceName());
        deviceTiktokInfo.setDeviceRemark(deviceTiktokInfoDto.getDeviceRemark());
        deviceTiktokInfo.setGroupId(deviceTiktokInfoDto.getGroupId());
        deviceTiktokInfo.setConfigId(0L);
        deviceTiktokInfo.setUpdateTime(now);
        deviceTiktokInfo.setAutoReplace(Tools.getInteger(deviceTiktokInfoDto.getAutoReplace()));
        deviceTiktokInfo.setConfigRule(deviceTiktokInfoDto.getConfigRule());
        deviceTiktokInfoMapper.updateById(deviceTiktokInfo);

        //更新redis
        Object object_mobile = redisTemplate.opsForValue().get(String.format(RedisCacheKeyEnum.DEVICE_INFO_TIKTOK.getKey(), deviceTiktokInfoDto.getId()));
        if(object_mobile != null){
            JSONObject jsonObject = JSONObject.parseObject(object_mobile.toString());
            jsonObject.put("configId", deviceTiktokInfoDto.getConfigId());
            jsonObject.put("deviceRemark", deviceTiktokInfoDto.getDeviceRemark());
            redisTemplate.opsForValue().set(String.format(RedisCacheKeyEnum.DEVICE_INFO_TIKTOK.getKey(), deviceTiktokInfoDto.getId()), jsonObject.toJSONString());
        }

        //需要将配置方案当中的其他信息添加到Redis当中得 设备消息回复配置信息
//        ConfigPlan configPlan = configPlanMapper.selectById(deviceTiktokInfo.getConfigId(), deviceTiktokInfo.getMerId());
//        if(configPlan != null && configPlan.getOtherId() != null){
//            SysPlugin sysPlugin = sysPluginMapper.selectById(configPlan.getOtherId(), deviceTiktokInfoDto.getMerId());
//            if(sysPlugin != null){
//                redisTemplate.opsForValue().set(String.format(RedisCacheKeyEnum.DEVICE_MSG_CONFIG.getKey(), deviceTiktokInfo.getId()) , sysPlugin.getData());
//            }
//        }
    }

    /**
     * 批量修改机器人信息
     * @author liuqi
     * @date 2021/8/25 11:38
     * @param deviceTiktokInfoBatchDto
     */
    public void batchUpdateDeviceTiktokInfo(DeviceTiktokInfoBatchDto deviceTiktokInfoBatchDto){

        if(deviceTiktokInfoBatchDto.getIdList() == null || deviceTiktokInfoBatchDto.getIdList().size() == 0){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入id参数");
        }

//        Long configId = deviceTiktokInfoBatchDto.getConfigId();
//        ConfigPlan configPlan = null;
//        if(configId != null){
//            configPlan = configPlanMapper.selectById(configId, deviceTiktokInfoBatchDto.getMerId());
//            if(configPlan == null){
//                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该配置方案不存在");
//            }
//        }

        Long groupId = deviceTiktokInfoBatchDto.getGroupId();
        if(groupId != null){
            DeviceGroup deviceGroup = deviceGroupMapper.selectById(groupId, deviceTiktokInfoBatchDto.getMerId());
            if(deviceGroup == null){
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该机器人分组不存在");
            }
        }

        //配置方案启用规则
        Integer configRule = deviceTiktokInfoBatchDto.getConfigRule();

        for(Long id : deviceTiktokInfoBatchDto.getIdList()){
            DeviceTiktokInfo deviceTiktokInfo = deviceTiktokInfoMapper.selectById(id, deviceTiktokInfoBatchDto.getMerId());
            if(deviceTiktokInfo == null){
                continue;
            }

            Integer now = DateUtil.getNowTime();

//            if(configId != null){
//                deviceTiktokInfo.setConfigId(configId);
//            }

            if(groupId != null){
                deviceTiktokInfo.setGroupId(groupId);
            }

            if(configRule != null){
                deviceTiktokInfo.setConfigRule(configRule);
            }

            deviceTiktokInfo.setUpdateTime(now);
            deviceTiktokInfo.setAutoReplace(Tools.getInteger(deviceTiktokInfoBatchDto.getAutoReplace()));
            deviceTiktokInfoMapper.updateById(deviceTiktokInfo);

            //更新redis
//            if(configId != null){
//                Object object_pc = redisTemplate.opsForValue().get(String.format(RedisCacheKeyEnum.DEVICE_INFO_TIKTOK.getKey(), id));
//                if(object_pc != null){
//                    JSONObject jsonObject = JSONObject.parseObject(object_pc.toString());
//                    jsonObject.put("configId", deviceTiktokInfoBatchDto.getConfigId());
//                    redisTemplate.opsForValue().set(String.format(RedisCacheKeyEnum.DEVICE_INFO_TIKTOK.getKey(), id), jsonObject.toJSONString());
//                }
//                Object object_mobile = redisTemplate.opsForValue().get(String.format(RedisCacheKeyEnum.DEVICE_INFO_TIKTOK.getKey(), id));
//                if(object_mobile != null){
//                    JSONObject jsonObject = JSONObject.parseObject(object_mobile.toString());
//                    jsonObject.put("configId", deviceTiktokInfoBatchDto.getConfigId());
//                    redisTemplate.opsForValue().set(String.format(RedisCacheKeyEnum.DEVICE_INFO_TIKTOK.getKey(), id), jsonObject.toJSONString());
//                }
//
//                //需要将配置方案当中的其他信息添加到Redis当中得 设备消息回复配置信息
//                if(configPlan != null && configPlan.getOtherId() != null){
//                    //需要将配置方案当中的其他信息添加到Redis当中得 设备消息回复配置信息
//                    SysPlugin sysPlugin = sysPluginMapper.selectById(configPlan.getOtherId(), deviceTiktokInfoBatchDto.getMerId());
//                    if(sysPlugin != null){
//                        redisTemplate.opsForValue().set(String.format(RedisCacheKeyEnum.DEVICE_MSG_CONFIG.getKey(), deviceTiktokInfo.getId()) , sysPlugin.getData());
//                    }
//                }
//            }
        }
    }

    /**
     * 抖音设备机器人删除
     * @author liuqi
     * @date 2021/8/13 11:38
     * @param deviceTiktokInfoDelDto
     * @return null
     */
    public Boolean delDeviceTiktokInfo(DeviceTiktokInfoDelDto deviceTiktokInfoDelDto){

        //主键idList
        List<Long> idList = deviceTiktokInfoDelDto.getIdList();

        if(idList == null || idList.size() == 0){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入id");
        }
        for (Long id : idList){
            DeviceTiktokInfo deviceTiktokInfo = deviceTiktokInfoMapper.selectById(id, deviceTiktokInfoDelDto.getMerId());
            if(deviceTiktokInfo != null){
                deviceTiktokInfoMapper.deleteById(id, deviceTiktokInfoDelDto.getMerId());
                //清除机器人所有运营商缓存
                redisTemplate.delete(String.format(RedisCacheKeyEnum.DEVICE_MERCHANT.getKey(), deviceTiktokInfo.getDeviceId()));
                //删除机器人移动端缓存
                redisTemplate.delete(String.format(RedisCacheKeyEnum.DEVICE_INFO_TIKTOK.getKey(), deviceTiktokInfo.getId()));
            }
        }
        return true;
    }

    /**
     * 更新电脑端客户端软件
     * @author liuqi
     * @date 2021/8/13 11:38
     * @param deviceTiktokInfoIdDto
     * @return null
     */
    public void updatePcClientSoft(DeviceTiktokInfoIdDto deviceTiktokInfoIdDto){
        if(deviceTiktokInfoIdDto.getId() == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入id参数");
        }

        DeviceTiktokInfo deviceTiktokInfo = deviceTiktokInfoMapper.selectById(deviceTiktokInfoIdDto.getId(), deviceTiktokInfoIdDto.getMerId());

        if(deviceTiktokInfo == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该机器人不存在");
        }

        //从缓存中换取抖音设备移动端信息
        Object object = redisTemplate.opsForValue().get(String.format(RedisCacheKeyEnum.DEVICE_INFO_TIKTOK.getKey(), deviceTiktokInfo.getId()));
        DeviceInfoTiktokCacheDto deviceInfoTiktokCacheDto = JSONObject.parseObject(String.valueOf(object), DeviceInfoTiktokCacheDto.class);

        //PC端抖音设备信息不为空
        if(deviceInfoTiktokCacheDto == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "电脑端机器人还未曾登录过，不能更新版本");
        }

        //更新客户端版本状态(0-无更新；1-有更新；2-更新中; 3-更新失败(当状态为2时，验证更新时间是否超过5分钟，超过就更新失败)")
        Integer updateClientVersionStatus = deviceInfoTiktokCacheDto.getUpdateClientVersionStatus();
        Integer updateClientVersionTime = deviceInfoTiktokCacheDto.getUpdateClientVersionTime();
        if(updateClientVersionStatus != null && updateClientVersionStatus.intValue() == 2){
            if(DateUtil.getNowTime() - updateClientVersionTime < Const.Device.UPDATE_VERSION_VALIDITY_TIME){
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "机器人版本正在更新中 ，请稍后再试");
            }
        }

        DeviceVersion deviceVersion = deviceVersionMapper.selectByTypeId(DeviceTypeEnum.TIKTOK.getId());
        if(deviceVersion == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "机器人最新版本为空");
        }

        //发送MQ消息
        MsgDto<UpdateClientAppDto> msgDto = new MsgDto<>();
        UpdateClientAppDto updateClientAppDto = new UpdateClientAppDto();
        msgDto.setContent(updateClientAppDto);
        msgDto.setId(IdWorker.getId());
        msgDto.setDeviceType(deviceTiktokInfo.getRecvmsgType());
        msgDto.setDeviceUniqueId(deviceTiktokInfo.getId());
        msgDto.setMerId(deviceTiktokInfo.getMerId());
        msgDto.setMsgType(MessageFuncEnum.UPDATE_CLIENT.getValue());
        updateClientAppDto.setUpdateType(1); //常规更新
        updateClientAppDto.setIsRunApp(1);   //启动
        updateClientAppDto.setNewVersion(deviceVersion.getVersion());
        noticeMsgPushProducerService.updateClientApp(msgDto);

        //修改Redis状态
        deviceInfoTiktokCacheDto.setUpdateClientVersionStatus(2);
        deviceInfoTiktokCacheDto.setUpdateClientVersionTime(DateUtil.getNowTime());
        redisTemplate.opsForValue().set(String.format(RedisCacheKeyEnum.DEVICE_INFO_TIKTOK.getKey(), deviceTiktokInfo.getId()), Tools.getStrEmpty(JSONObject.toJSONString(deviceInfoTiktokCacheDto)));
    }

    /**
     * 批量更新电脑端客户端软件
     * @author liuqi
     * @date 2021/8/13 11:38
     * @param deviceTiktokInfoIdListDto
     * @return null
     */
    public void batchUpdatePcClientSoft(DeviceTiktokInfoIdListDto deviceTiktokInfoIdListDto){

        List<Long> idList = deviceTiktokInfoIdListDto.getIdList();

        if(idList == null || idList.size() == 0){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入id参数");
        }

        for (Long id : idList){
            DeviceTiktokInfo deviceTiktokInfo = deviceTiktokInfoMapper.selectById(id, deviceTiktokInfoIdListDto.getMerId());
            if(deviceTiktokInfo == null){
                continue;
            }

            //从缓存中换取抖音设备PC端信息
            Object object = redisTemplate.opsForValue().get(String.format(RedisCacheKeyEnum.DEVICE_INFO_TIKTOK.getKey(), deviceTiktokInfo.getId()));
            DeviceInfoTiktokCacheDto deviceInfoPcWeChatCacheDto = JSONObject.parseObject(String.valueOf(object), DeviceInfoTiktokCacheDto.class);

            //PC端抖音设备信息不为空
            if(deviceInfoPcWeChatCacheDto == null){
                continue;
            }

            //更新客户端版本状态(0-无更新；1-有更新；2-更新中; 3-更新失败(当状态为2时，验证更新时间是否超过5分钟，超过就更新失败)")
            Integer updateClientVersionStatus = deviceInfoPcWeChatCacheDto.getUpdateClientVersionStatus();
            Integer updateClientVersionTime = deviceInfoPcWeChatCacheDto.getUpdateClientVersionTime();
            if(updateClientVersionStatus != null && updateClientVersionStatus.intValue() == 2){
                if(DateUtil.getNowTime() - updateClientVersionTime < Const.Device.UPDATE_VERSION_VALIDITY_TIME){
                    continue;
                }
            }

            DeviceVersion deviceVersion = deviceVersionMapper.selectByTypeId(DeviceTypeEnum.TIKTOK.getId());
            if(deviceVersion == null){
                continue;
            }


            //发送MQ消息
            MsgDto<UpdateClientAppDto> msgDto = new MsgDto<>();
            UpdateClientAppDto updateClientAppDto = new UpdateClientAppDto();
            msgDto.setContent(updateClientAppDto);
            msgDto.setId(IdWorker.getId());
            msgDto.setDeviceType(deviceTiktokInfo.getRecvmsgType());
            msgDto.setDeviceUniqueId(deviceTiktokInfo.getId());
            msgDto.setMerId(deviceTiktokInfo.getMerId());
            msgDto.setMsgType(MessageFuncEnum.UPDATE_CLIENT.getValue());
            updateClientAppDto.setUpdateType(1); //强制更新
            updateClientAppDto.setIsRunApp(1);   //启动
            updateClientAppDto.setNewVersion(deviceVersion.getVersion());
            noticeMsgPushProducerService.updateClientApp(msgDto);

            //修改Redis状态
            deviceInfoPcWeChatCacheDto.setUpdateClientVersionStatus(2);
            deviceInfoPcWeChatCacheDto.setUpdateClientVersionTime(DateUtil.getNowTime());
            redisTemplate.opsForValue().set(String.format(RedisCacheKeyEnum.DEVICE_INFO_TIKTOK.getKey(), deviceTiktokInfo.getId()), Tools.getStrEmpty(JSONObject.toJSONString(deviceInfoPcWeChatCacheDto)));
        }


    }

    /**
     * 重启电脑端客户端软件
     * @author liuqi
     * @date 2021/8/13 11:38
     * @param deviceTiktokInfoIdDto
     * @return null
     */
    public void restartPcClientSoft(DeviceTiktokInfoIdDto deviceTiktokInfoIdDto){
        if(deviceTiktokInfoIdDto.getId() == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入id参数");
        }

        DeviceTiktokInfo deviceTiktokInfo = deviceTiktokInfoMapper.selectById(deviceTiktokInfoIdDto.getId(), deviceTiktokInfoIdDto.getMerId());

        if(deviceTiktokInfo == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该机器人不存在");
        }

        //发送MQ消息
        MsgDto<CloseClientAppDto> msgDto = new MsgDto<>();
        CloseClientAppDto closeClientAppDto = new CloseClientAppDto();
        msgDto.setContent(closeClientAppDto);
        msgDto.setId(IdWorker.getId());
        msgDto.setDeviceType(deviceTiktokInfo.getRecvmsgType());
        msgDto.setDeviceUniqueId(deviceTiktokInfo.getId());
        msgDto.setMerId(deviceTiktokInfo.getMerId());
        msgDto.setMsgType(MessageFuncEnum.CLOSE_CLIENT_APP.getValue());
        closeClientAppDto.setOptType(2); //重启客户端软件
        noticeMsgPushProducerService.closeClientApp(msgDto);

    }

    /**
     * 批量重启电脑端客户端软件
     * @author liuqi
     * @date 2021/8/13 11:38
     * @param deviceTiktokInfoIdListDto
     * @return null
     */
    public void batchRestartPcClientSoft(DeviceTiktokInfoIdListDto deviceTiktokInfoIdListDto){
        List<Long> idList = deviceTiktokInfoIdListDto.getIdList();
        if(idList == null || idList.size() == 0){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入id参数");
        }
        for(Long id : idList){
            DeviceTiktokInfo deviceTiktokInfo = deviceTiktokInfoMapper.selectById(id, deviceTiktokInfoIdListDto.getMerId());
            if(deviceTiktokInfo == null){
                continue;
            }
            //发送MQ消息
            MsgDto<CloseClientAppDto> msgDto = new MsgDto<>();
            CloseClientAppDto closeClientAppDto = new CloseClientAppDto();
            msgDto.setContent(closeClientAppDto);
            msgDto.setId(IdWorker.getId());
            msgDto.setDeviceType(deviceTiktokInfo.getRecvmsgType());
            msgDto.setDeviceUniqueId(deviceTiktokInfo.getId());
            msgDto.setMerId(deviceTiktokInfo.getMerId());
            msgDto.setMsgType(MessageFuncEnum.CLOSE_CLIENT_APP.getValue());
            closeClientAppDto.setOptType(2); //重启客户端软件
            noticeMsgPushProducerService.closeClientApp(msgDto);
        }
    }

    /**
     * 退出电脑端客户端软件
     * @author liuqi
     * @date 2021/8/13 11:38
     * @param deviceTiktokInfoIdDto
     * @return null
     */
    public void quitPcClientSoft(DeviceTiktokInfoIdDto deviceTiktokInfoIdDto){
        if(deviceTiktokInfoIdDto.getId() == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入id参数");
        }

        DeviceTiktokInfo deviceTiktokInfo = deviceTiktokInfoMapper.selectById(deviceTiktokInfoIdDto.getId(), deviceTiktokInfoIdDto.getMerId());

        if(deviceTiktokInfo == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该机器人不存在");
        }

        //发送MQ消息
        MsgDto<CloseClientAppDto> msgDto = new MsgDto<>();
        CloseClientAppDto closeClientAppDto = new CloseClientAppDto();
        msgDto.setContent(closeClientAppDto);
        msgDto.setId(IdWorker.getId());
        msgDto.setDeviceType(deviceTiktokInfo.getRecvmsgType());
        msgDto.setDeviceUniqueId(deviceTiktokInfo.getId());
        msgDto.setMerId(deviceTiktokInfo.getMerId());
        msgDto.setMsgType(MessageFuncEnum.CLOSE_CLIENT_APP.getValue());
        closeClientAppDto.setOptType(4); //退出客户端软件
        noticeMsgPushProducerService.closeClientApp(msgDto);
    }

    /**
     * 批量退出电脑端客户端软件
     * @author liuqi
     * @date 2021/8/13 11:38
     * @param deviceTiktokInfoIdListDto
     * @return null
     */
    public void batchQuitPcClientSoft(DeviceTiktokInfoIdListDto deviceTiktokInfoIdListDto){
        List<Long> idList = deviceTiktokInfoIdListDto.getIdList();
        if(idList == null || idList.size() == 0){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入id参数");
        }
        for(Long id : idList){
            DeviceTiktokInfo deviceTiktokInfo = deviceTiktokInfoMapper.selectById(id, deviceTiktokInfoIdListDto.getMerId());
            if(deviceTiktokInfo == null){
                continue;
            }
            //发送MQ消息
            MsgDto<CloseClientAppDto> msgDto = new MsgDto<>();
            CloseClientAppDto closeClientAppDto = new CloseClientAppDto();
            msgDto.setContent(closeClientAppDto);
            msgDto.setId(IdWorker.getId());
            msgDto.setDeviceType(deviceTiktokInfo.getRecvmsgType());
            msgDto.setDeviceUniqueId(deviceTiktokInfo.getId());
            msgDto.setMerId(deviceTiktokInfo.getMerId());
            msgDto.setMsgType(MessageFuncEnum.CLOSE_CLIENT_APP.getValue());
            closeClientAppDto.setOptType(4); //退出客户端软件
            noticeMsgPushProducerService.closeClientApp(msgDto);
        }
    }

    /**
     * 退出电脑端微信
     * @author liuqi
     * @date 2021/8/13 11:38
     * @param deviceTiktokInfoIdDto
     * @return null
     */
    public void quitPcWechat(DeviceTiktokInfoIdDto deviceTiktokInfoIdDto){
        if(deviceTiktokInfoIdDto.getId() == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入id参数");
        }

        DeviceTiktokInfo deviceTiktokInfo = deviceTiktokInfoMapper.selectById(deviceTiktokInfoIdDto.getId(), deviceTiktokInfoIdDto.getMerId());

        if(deviceTiktokInfo == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该机器人不存在");
        }

        //发送MQ消息
        MsgDto<CloseClientAppDto> msgDto = new MsgDto<>();
        CloseClientAppDto closeClientAppDto = new CloseClientAppDto();
        msgDto.setContent(closeClientAppDto);
        msgDto.setId(IdWorker.getId());
        msgDto.setDeviceType(deviceTiktokInfo.getRecvmsgType());
        msgDto.setDeviceUniqueId(deviceTiktokInfo.getId());
        msgDto.setMerId(deviceTiktokInfo.getMerId());
        msgDto.setMsgType(MessageFuncEnum.CLOSE_CLIENT_APP.getValue());
        closeClientAppDto.setOptType(5); //退出电脑端微信
        noticeMsgPushProducerService.closeClientApp(msgDto);
    }

    /**
     * 批量退出电脑端微信
     * @author liuqi
     * @date 2021/8/13 11:38
     * @param deviceTiktokInfoIdListDto
     * @return null
     */
    public void batchQuitPcWechat(DeviceTiktokInfoIdListDto deviceTiktokInfoIdListDto){
        List<Long> idList = deviceTiktokInfoIdListDto.getIdList();
        if(idList == null || idList.size() == 0){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入id参数");
        }
        for(Long id : idList){
            DeviceTiktokInfo deviceTiktokInfo = deviceTiktokInfoMapper.selectById(id, deviceTiktokInfoIdListDto.getMerId());

            if(deviceTiktokInfo == null){
                continue;
            }

            //发送MQ消息
            MsgDto<CloseClientAppDto> msgDto = new MsgDto<>();
            CloseClientAppDto closeClientAppDto = new CloseClientAppDto();
            msgDto.setContent(closeClientAppDto);
            msgDto.setId(IdWorker.getId());
            msgDto.setDeviceType(deviceTiktokInfo.getRecvmsgType());
            msgDto.setDeviceUniqueId(deviceTiktokInfo.getId());
            msgDto.setMerId(deviceTiktokInfo.getMerId());
            msgDto.setMsgType(MessageFuncEnum.CLOSE_CLIENT_APP.getValue());
            closeClientAppDto.setOptType(5); //退出电脑端微信
            noticeMsgPushProducerService.closeClientApp(msgDto);
        }
    }

    /**
     * 购买授权
     * @author liuqi
     * @date 2021/8/25 11:38
     * @param deviceTiktokInfoBuyAuthDto
     */
    @Transactional
    public DeviceTiktokInfoAddVo buyDeviceAuth(DeviceTiktokInfoBuyAuthDto deviceTiktokInfoBuyAuthDto){

        DeviceTiktokInfoAddVo deviceTiktokInfoAddVo = new DeviceTiktokInfoAddVo();
        String trandeNo = Tools.getCurrentTimeByFormat("yyyyMMdd") + IdWorker.getIdStr();
        Integer now = DateUtil.getNowTime();
        Long merId = deviceTiktokInfoBuyAuthDto.getMerId();

        //取出机器人列表
        List<Long> idList = deviceTiktokInfoBuyAuthDto.getIdList();
        if(idList == null || idList.size() == 0){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请选择设备id");
        }

        //支付类型
        Integer payType = deviceTiktokInfoBuyAuthDto.getPayType();
        if(payType == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入支付类型");
        }

        //购买产品
        String productCode_auth = deviceTiktokInfoBuyAuthDto.getProductCode();
        if(StringUtils.isBlank(productCode_auth)){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请选择授权产品");
        }
        DeviceProduct deviceProduct_auth = deviceProductMapper.selectByCode(productCode_auth);
        if(deviceProduct_auth == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "系统还未配置该设备产品功能");
        }

        //List<String> productCodeList = JSONObject.parseArray(deviceProduct_auth.getCodes(), String.class);

        //从枚举中获取关联的产品
        TiktokDeviceProductEnum deviceProductEnum = TiktokDeviceProductEnum.getValue(deviceProduct_auth.getCode());
        List<String> productCodeList = JSONObject.parseArray(deviceProductEnum.getCodes(), String.class);
        if(productCodeList == null || productCodeList.size() == 0){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "系统还没配置该设备产品功能");
        }

        //判断支付类型
        if(payType.intValue() == PaymentTypeEnum.PAY_BALANCE.getId().intValue()) {//余额支付

            //授权类型(0试用;1月卡;2年卡)
            Integer authType = deviceTiktokInfoBuyAuthDto.getAuthType();
            if(authType == null){
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入授权类型");
            }

            //授权数量
            Integer quantity = deviceTiktokInfoBuyAuthDto.getQuantity();
            if(quantity == null){
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入购买时长");
            }

            if(authType.intValue() == DeviceAuthTypeEnum.DAT_MONTH.getId().intValue()){ //按月购买
                if(quantity.intValue() >120){ //不能超过120月
                    throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "最大购买月数不能超过120个月");
                }
            }else{ //按年购买
                if(quantity.intValue() >10){ //不能超过10年
                    throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "最大购买年数不能超过10年");
                }
            }

            //保存到数据库当中的购买月数，按年买需要乘以12月
            Integer quantity_db = 0;

            //总金额
            DeviceAmountDto deviceAmountDto = new DeviceAmountDto();
            BeanUtils.copyProperties(deviceTiktokInfoBuyAuthDto, deviceAmountDto);
            deviceAmountDto.setIdList(idList);
            deviceAmountDto.setOperType(2); //购买授权
            DeviceAmountVo deviceAmountVo = getAmount(deviceAmountDto);
            Double amountTotal = Tools.getDouble(deviceAmountVo.getAmountTotal());

            if(amountTotal.doubleValue() <= 0){
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "选择授权时长已经存在");
            }

            //查询产品的总价格
            DevicePrice devicePrice_buy = devicePriceMapper.selectByAuthType(authType, productCode_auth, DeviceTypeEnum.TIKTOK_VALUE);
            if(devicePrice_buy == null){
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "系统还未配置产品的价格");
            }
            //all产品
            Double price_all = Tools.getDouble(devicePrice_buy.getPrice());
            //分别查询该产品包含的产品的总价格
            Double price_total = 0.00D;
            for(String productCode : productCodeList){
                //查询产品价格
                DevicePrice devicePrice = devicePriceMapper.selectByAuthType(authType, productCode, DeviceTypeEnum.TIKTOK_VALUE);
                if(devicePrice == null){
                    throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "系统还未配置好产品的价格");
                }
                price_total = Math.add(price_total, Tools.getDouble(devicePrice.getPrice()));
            }
            //总单价的优惠
            Double price_discount = Math.sub(price_total, price_all);


            //新的到期时间
            Integer expired_time = 0;

            //保存账户余额
            //处理余额支付信息
            //查询账号信息
            Merchant merchant = merchantMapper.selectById(merId);
            if(merchant == null) {
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该运营商不存在");
            }

            //判断余额大小
            Double balance = merchant.getBalance();
            if(balance.doubleValue() < amountTotal.doubleValue()){ //不够支付
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "账户余额不足");
            }

            //修改账户余额
            merchant.setBalance(balance - amountTotal);
            merchant.setUpdateTime(now);
            merchantMapper.updateBalance(merchant);

            //添加账户明细
            MerAccDetail merAccDetail = new MerAccDetail();
            merAccDetail.setId(IdWorker.getId());
            merAccDetail.setMerId(merchant.getId());
            merAccDetail.setOperateType(2);//支出
            merAccDetail.setMoney(merchant.getBalance());
            merAccDetail.setCgMoney(amountTotal);
            merAccDetail.setSourceType(MerAccDetailSourceTypeEnum.DEVICE_PC_AUTH.getId());
            merAccDetail.setSubtype(productCode_auth);
            merAccDetail.setTradeno(trandeNo);
            merAccDetail.setCreateTime(now);
            merAccDetail.setUpdateTime(now);
            merAccDetailMapper.insert(merAccDetail);

            //循环批量操作的机器人
            for(Long deviceUniqueId : idList){

                //查询机器人信息
                DeviceTiktokInfo deviceTiktokInfo = deviceTiktokInfoMapper.selectById(deviceUniqueId, deviceTiktokInfoBuyAuthDto.getMerId());
                if(deviceTiktokInfo == null){
                    throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "选择的机器人不存在");
                }
                String deviceId = deviceTiktokInfo.getDeviceId();

                //本次授权开始时间默认为现在
                Integer begin_time = deviceAuthService.selectEarliestAuthByDeviceIdAndProductCodeList(deviceId, productCodeList, now);

                //选择全包套餐包时的到期时间，如果单个基础包购买，则另外判断到期时间
                if (authType.intValue() == DeviceAuthTypeEnum.DAT_MONTH.getId().intValue()) {//按月购买
                    //新的到期时间=现在+月数*30天*24小时*3600秒
                    expired_time = begin_time + quantity * 30 * 24 * 3600;
                    quantity_db = quantity;
                }else{//按年购买
                    //新的到期时间=现在+年数*12月*30天*24小时*3600秒
                    expired_time = begin_time + quantity * 12 * 30 * 24 * 3600;
                    quantity_db = quantity * 12;
                }

                //判断购买的产品类型（全包类型需要补差价）
                if(productCodeList.size() == 1){ //单个基础包，则需重新设置到期时间，直接时间累加
                    Integer beginTime_one = 0;
                    Integer expireTime_one = 0;
                    String productCode = productCodeList.get(0);

                    //添加机器人授权表-如果没有则新增，有则修改
                    DeviceAuth deviceAuth = deviceAuthMapper.selectByDeviceIdAndProductCode(deviceId, productCode);
                    if(deviceAuth != null){//修改
                        //判断旧到期时间是否已经过期
                        Integer old_expireTime = Tools.getInteger(deviceAuth.getExpireTime());
                        if(old_expireTime <= now){//已经到期，则从今天开始算
                            beginTime_one = now;
                            expireTime_one = beginTime_one + quantity_db * 30 * 24 * 3600;
                        }else{
                            beginTime_one = old_expireTime;
                            expireTime_one = beginTime_one + quantity_db * 30 * 24 * 3600;
                        }
                        deviceAuth.setExpireTime(expireTime_one);
                        deviceAuth.setUpdateTime(now);
                        deviceAuth.setAuthType(authType);
                        deviceAuthMapper.updateById(deviceAuth);
                    }else{
                        deviceAuth = new DeviceAuth();
                        deviceAuth.setId(IdWorker.getId());
                        deviceAuth.setDeviceId(deviceTiktokInfo.getDeviceId());
                        deviceAuth.setDeviceUniqueId(deviceTiktokInfo.getId());
                        deviceAuth.setDeviceType(DeviceTypeEnum.TIKTOK.getKey());
                        deviceAuth.setDeviceTypeId(DeviceTypeEnum.TIKTOK.getId());
                        deviceAuth.setProductCode(productCode);
                        beginTime_one = now;
                        expireTime_one = beginTime_one + quantity_db * 30 * 24 * 3600;
                        deviceAuth.setExpireTime(expireTime_one);
                        deviceAuth.setCreateTime(now);
                        deviceAuth.setUpdateTime(now);
                        deviceAuth.setAuthType(authType);
                        deviceAuthMapper.insert(deviceAuth);
                    }

                    //添加机器人授权明细表
                    DeviceAuthDetail deviceAuthDetail = new DeviceAuthDetail();
                    deviceAuthDetail.setId(IdWorker.getId());
                    deviceAuthDetail.setMerId(deviceTiktokInfoBuyAuthDto.getMerId());
                    deviceAuthDetail.setDeviceUniqueId(deviceTiktokInfo.getId());
                    deviceAuthDetail.setDeviceId(deviceTiktokInfo.getDeviceId());
                    deviceAuthDetail.setDeviceType(DeviceTypeEnum.TIKTOK.getKey());
                    deviceAuthDetail.setDeviceTypeId(DeviceTypeEnum.TIKTOK.getId());
                    deviceAuthDetail.setProductCode(productCode);
                    deviceAuthDetail.setAuthType(deviceTiktokInfoBuyAuthDto.getAuthType());
                    deviceAuthDetail.setQuantity(quantity_db); //试用为0
                    deviceAuthDetail.setBeginTime(beginTime_one);
                    deviceAuthDetail.setExpireTime(expireTime_one);
                    deviceAuthDetail.setPayTime(now);
                    deviceAuthDetail.setPayType(deviceTiktokInfoBuyAuthDto.getPayType());
                    deviceAuthDetail.setTradeno(trandeNo);
                    deviceAuthDetail.setAmount(amountTotal);
                    deviceAuthDetail.setRemark("余额支付");
                    deviceAuthDetail.setCreateTime(now);
                    deviceAuthDetail.setUpdateTime(now);
                    deviceAuthDetailMapper.insert(deviceAuthDetail);
                }else{ //全包产品
                    for (String productCode : productCodeList) {
                        //查询旧授权
                        DeviceAuth deviceAuth = deviceAuthMapper.selectByDeviceIdAndProductCode(deviceId, productCode);
                        //还未授权
                        if (deviceAuth == null) {
                            //封装产品授权记录
                            DeviceAuthDetail deviceAuthDetail = new DeviceAuthDetail();
                            deviceAuthDetail.setId(IdWorker.getId());
                            deviceAuthDetail.setMerId(merId);
                            deviceAuthDetail.setDeviceUniqueId(deviceTiktokInfo.getId());
                            deviceAuthDetail.setDeviceId(deviceTiktokInfo.getDeviceId());
                            deviceAuthDetail.setDeviceType(DeviceTypeEnum.TIKTOK.getKey());
                            deviceAuthDetail.setDeviceTypeId(DeviceTypeEnum.TIKTOK.getId());
                            deviceAuthDetail.setProductCode(productCode);
                            deviceAuthDetail.setAuthType(authType);
                            deviceAuthDetail.setQuantity(quantity_db);
                            deviceAuthDetail.setPayTime(now);
                            deviceAuthDetail.setPayType(PaymentTypeEnum.PAY_BALANCE.getId());
                            deviceAuthDetail.setTradeno(trandeNo);
                            deviceAuthDetail.setRemark("余额支付");
                            deviceAuthDetail.setCreateTime(now);
                            deviceAuthDetail.setUpdateTime(now);
                            deviceAuthDetail.setAmount(amountTotal);
                            deviceAuthDetail.setBeginTime(begin_time);
                            deviceAuthDetail.setExpireTime(expired_time);
                            //插入授权数据明细
                            deviceAuthDetailMapper.insert(deviceAuthDetail);

                            //插入授权数据
                            //添加机器人授权表
                            deviceAuth = new DeviceAuth();
                            deviceAuth.setId(IdWorker.getId());
                            deviceAuth.setDeviceId(deviceTiktokInfo.getDeviceId());
                            deviceAuth.setDeviceUniqueId(deviceTiktokInfo.getId());
                            deviceAuth.setDeviceType(DeviceTypeEnum.TIKTOK.getKey());
                            deviceAuth.setDeviceTypeId(DeviceTypeEnum.TIKTOK.getId());
                            deviceAuth.setAuthType(authType);
                            deviceAuth.setProductCode(productCode);
                            //新授权，到期时间从今天开始算
                            deviceAuth.setExpireTime(expired_time);
                            deviceAuth.setCreateTime(now);
                            deviceAuth.setUpdateTime(now);
                            deviceAuthMapper.insert(deviceAuth);

                        } else { //授权存在，需判断授权的结束时间
                            //旧到期时间
                            Integer old_expireTime = Tools.getInteger(deviceAuth.getExpireTime());
                            //判断旧授权是否已经过期，
                            if (old_expireTime <= now) { //已经过期
                                //封装产品授权记录
                                DeviceAuthDetail deviceAuthDetail = new DeviceAuthDetail();
                                deviceAuthDetail.setId(IdWorker.getId());
                                deviceAuthDetail.setMerId(merId);
                                deviceAuthDetail.setDeviceUniqueId(deviceTiktokInfo.getId());
                                deviceAuthDetail.setDeviceId(deviceTiktokInfo.getDeviceId());
                                deviceAuthDetail.setDeviceType(DeviceTypeEnum.TIKTOK.getKey());
                                deviceAuthDetail.setDeviceTypeId(DeviceTypeEnum.TIKTOK.getId());
                                deviceAuthDetail.setProductCode(productCode);
                                deviceAuthDetail.setAuthType(authType);
                                deviceAuthDetail.setQuantity(quantity_db);
                                deviceAuthDetail.setPayTime(now);
                                deviceAuthDetail.setPayType(PaymentTypeEnum.PAY_BALANCE.getId());
                                deviceAuthDetail.setTradeno(trandeNo);
                                deviceAuthDetail.setRemark("余额支付");
                                deviceAuthDetail.setCreateTime(now);
                                deviceAuthDetail.setUpdateTime(now);
                                deviceAuthDetail.setAmount(amountTotal);
                                deviceAuthDetail.setBeginTime(begin_time);
                                deviceAuthDetail.setExpireTime(expired_time);
                                //插入授权数据明细
                                deviceAuthDetailMapper.insert(deviceAuthDetail);

                                //更新授权记录
                                deviceAuth.setAuthType(authType);
                                deviceAuth.setExpireTime(expired_time);
                                deviceAuth.setUpdateTime(now);
                                deviceAuthMapper.updateById(deviceAuth);

                                //旧到期时间大于当前时间，且小于授权结束时间，则补差价
                            } else if(old_expireTime > now && old_expireTime < expired_time){

                                //封装产品授权记录
                                DeviceAuthDetail deviceAuthDetail = new DeviceAuthDetail();
                                deviceAuthDetail.setId(IdWorker.getId());
                                deviceAuthDetail.setMerId(merId);
                                deviceAuthDetail.setDeviceUniqueId(deviceTiktokInfo.getId());
                                deviceAuthDetail.setDeviceId(deviceTiktokInfo.getDeviceId());
                                deviceAuthDetail.setDeviceType(DeviceTypeEnum.TIKTOK.getKey());
                                deviceAuthDetail.setDeviceTypeId(DeviceTypeEnum.TIKTOK.getId());
                                deviceAuthDetail.setProductCode(productCode);
                                deviceAuthDetail.setAuthType(authType);
                                deviceAuthDetail.setQuantity(quantity_db);
                                deviceAuthDetail.setPayTime(now);
                                deviceAuthDetail.setPayType(PaymentTypeEnum.PAY_BALANCE.getId());
                                deviceAuthDetail.setTradeno(trandeNo);
                                deviceAuthDetail.setRemark("余额支付");
                                deviceAuthDetail.setCreateTime(now);
                                deviceAuthDetail.setUpdateTime(now);
                                deviceAuthDetail.setAmount(amountTotal);
                                deviceAuthDetail.setBeginTime(begin_time);
                                deviceAuthDetail.setExpireTime(expired_time);
                                //插入授权数据明细
                                deviceAuthDetailMapper.insert(deviceAuthDetail);
                                //更新授权记录
                                deviceAuth.setAuthType(authType);
                                deviceAuth.setExpireTime(expired_time);
                                deviceAuth.setUpdateTime(now);
                                deviceAuthMapper.updateById(deviceAuth);
                            }
                        }
                    }
                }

                //封装机器人授权信息
                List<DeviceInfoTiktokCacheDto.DeviceProductAuth> deviceProductAuthList = new ArrayList<>();
                //查询该机器人的所有产品授权信息
                DeviceAuthQuery deviceAuthQuery = new DeviceAuthQuery();
                deviceAuthQuery.setDeviceId(deviceTiktokInfo.getDeviceId());
                deviceAuthQuery.setDeviceType(DeviceTypeEnum.TIKTOK.getKey());
                List<DeviceAuth> deviceAuthList = deviceAuthMapper.findByList(deviceAuthQuery);
                if(deviceAuthList != null && deviceAuthList.size() > 0){
                    for(DeviceAuth deviceAuth : deviceAuthList){
                        //机器人redis缓存信息-产品授权
                        DeviceInfoTiktokCacheDto.DeviceProductAuth deviceProductAuth = new DeviceInfoTiktokCacheDto.DeviceProductAuth();
                        deviceProductAuth.setAuthType(deviceAuth.getAuthType());
                        deviceProductAuth.setExpireTime(deviceAuth.getExpireTime());
                        deviceProductAuth.setProductCode(deviceAuth.getProductCode());
                        deviceProductAuthList.add(deviceProductAuth);
                    }
                    //更新redis
                    Object object = redisTemplate.opsForValue().get(String.format(RedisCacheKeyEnum.DEVICE_INFO_TIKTOK.getKey(), deviceTiktokInfo.getId()));
                    if(object != null) { //修改
                        DeviceInfoTiktokCacheDto deviceInfoTiktokCacheDto = JSONObject.parseObject(object.toString(), DeviceInfoTiktokCacheDto.class);
                        if(deviceInfoTiktokCacheDto != null){
                            deviceInfoTiktokCacheDto.setDeviceAuths(deviceProductAuthList);
                        }
                        //更新移动端机器人redis
                        redisTemplate.opsForValue().set(String.format(RedisCacheKeyEnum.DEVICE_INFO_TIKTOK.getKey(), deviceTiktokInfo.getId()), Tools.getStrEmpty(JSONObject.toJSONString(deviceInfoTiktokCacheDto)));
                    }else{
                        DeviceInfoTiktokCacheDto deviceInfoTiktokCacheDto = new DeviceInfoTiktokCacheDto();
                        deviceInfoTiktokCacheDto.setMerId(deviceTiktokInfo.getMerId());
                        deviceInfoTiktokCacheDto.setDeviceId(deviceTiktokInfo.getDeviceId());
                        deviceInfoTiktokCacheDto.setDeviceUniqueId(deviceTiktokInfo.getId());
                        deviceInfoTiktokCacheDto.setConfigId(deviceTiktokInfo.getConfigId());
                        deviceInfoTiktokCacheDto.setDeviceAuths(deviceProductAuthList);
                        deviceInfoTiktokCacheDto.setMsgHandler(1);
                        //更新移动端机器人redis
                        redisTemplate.opsForValue().set(String.format(RedisCacheKeyEnum.DEVICE_INFO_TIKTOK.getKey(), deviceTiktokInfo.getId()), Tools.getStrEmpty(JSONObject.toJSONString(deviceInfoTiktokCacheDto)));
                    }
                }
            }
        }else if(payType.intValue() == PaymentTypeEnum.PAY_ALIPAY.getId().intValue()){ //支付宝支付
            //授权类型(0试用;1月卡;2年卡)
            Integer authType = deviceTiktokInfoBuyAuthDto.getAuthType();
            if(authType == null){
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入授权类型");
            }

            //授权数量
            Integer quantity = deviceTiktokInfoBuyAuthDto.getQuantity();
            if(quantity == null){
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入购买时长");
            }

            if(authType.intValue() == DeviceAuthTypeEnum.DAT_MONTH.getId().intValue()){ //按月购买
                if(quantity.intValue() >120){ //不能超过120月
                    throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "最大购买月数不能超过120个月");
                }
            }else{ //按年购买
                if(quantity.intValue() >10){ //不能超过10年
                    throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "最大购买年数不能超过10年");
                }
            }

            //保存到数据库当中的购买月数，按年买需要乘以12月
            Integer quantity_db = 0;

            //总金额
            DeviceAmountDto deviceAmountDto = new DeviceAmountDto();
            BeanUtils.copyProperties(deviceTiktokInfoBuyAuthDto, deviceAmountDto);
            deviceAmountDto.setIdList(idList);
            deviceAmountDto.setOperType(2); //购买授权
            DeviceAmountVo deviceAmountVo = getAmount(deviceAmountDto);
            Double amountTotal = Tools.getDouble(deviceAmountVo.getAmountTotal());

            if(amountTotal.doubleValue() <= 0){
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "选择授权时长已经存在");
            }

            //新的到期时间
            Integer expired_time = 0;

            //添加支付宝账单
            AlipayDetail alipayDetail = new AlipayDetail();
            alipayDetail.setId(IdWorker.getId());
            alipayDetail.setMerId(deviceTiktokInfoBuyAuthDto.getMerId());
            alipayDetail.setTradeno(trandeNo);
            alipayDetail.setType(AlipayTypeEnum.DEVICE_TIKTOK_AUTH.getId()); //续费抖音机器人
            alipayDetail.setSubtype(productCode_auth);

            //业务信息
            DeviceAuthBusinessInfo deviceAuthBusinessInfo = new DeviceAuthBusinessInfo();
            deviceAuthBusinessInfo.setDeviceUniqueIdList(deviceTiktokInfoBuyAuthDto.getIdList());
            deviceAuthBusinessInfo.setDeviceType(DeviceTypeEnum.TIKTOK.getKey());
            deviceAuthBusinessInfo.setDeviceTypeId(DeviceTypeEnum.TIKTOK.getId());
            deviceAuthBusinessInfo.setAuthType(deviceTiktokInfoBuyAuthDto.getAuthType());
            deviceAuthBusinessInfo.setQuantity(quantity);
            deviceAuthBusinessInfo.setAmount(amountTotal);
            deviceAuthBusinessInfo.setProductCode(productCode_auth);

            //查询产品价格
            DevicePrice devicePrice = devicePriceMapper.selectByAuthType(authType, productCode_auth, DeviceTypeEnum.TIKTOK_VALUE);
            if (devicePrice == null) {
                throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请先设置抖音设备机器该端的购买价格");
            }
            deviceAuthBusinessInfo.setPrice(devicePrice.getPrice());
            alipayDetail.setBusinessInfo(Tools.getStrEmpty(JSONObject.toJSONString(deviceAuthBusinessInfo)));

            alipayDetail.setAmount(amountTotal);
            alipayDetail.setStatus(AlipayStatusEnum.WAIT_BUYER_PAY.getId()); //等待付款
            alipayDetail.setCreateTime(now);
            alipayDetail.setUpdateTime(now);

            //请求支付宝申请订单
            AlipayDetailCreateDto alipayDetailCreateDto = new AlipayDetailCreateDto();
            alipayDetailCreateDto.setOutTradeNo(alipayDetail.getTradeno());
            alipayDetailCreateDto.setTotalAmount(alipayDetail.getAmount());
            alipayDetailCreateDto.setSubject(AlipayTypeEnum.DEVICE_TIKTOK_AUTH.getDesc());

            String alipayUrl = alipayDetailService.createAlipayDetail(alipayDetailCreateDto);
            if(StringUtils.isNotBlank(alipayUrl)){
                alipayDetail.setAlipayUrl(alipayUrl);
                //插入支付宝账单
                alipayDetailMapper.insertSelective(alipayDetail);
                //返回支付页面
                deviceTiktokInfoAddVo.setAlipayUrl(uzaiConsoleSysConfig.getAlipayPaypageUrl()+"?id=" + alipayDetail.getId());
            }else{
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "调用支付宝失败");
            }
        }

        return  deviceTiktokInfoAddVo;
    }

    /**
     * 查询添加或者购买总金额
     * @author liuqi
     * @date 2021/8/25 11:38
     * @param deviceAmountDto
     */
    public DeviceAmountVo getAmount(DeviceAmountDto deviceAmountDto){

        //操作类型(1-添加机器人；2-购买授权)
        Integer operType = deviceAmountDto.getOperType();
        if(deviceAmountDto.getOperType() == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入操作类型");
        }

        //类型类型id（8-抖音设备）
        Integer deviceTypeId = DeviceTypeEnum.TIKTOK.getId();
        if(deviceTypeId == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入机器人类型id");
        }

        //授权类型(1月卡;2年卡)
        Integer authType = deviceAmountDto.getAuthType();
        if(authType == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入授权类型");
        }

        //购买时长
        Integer quantity = deviceAmountDto.getQuantity();
        if(quantity == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入购买时长");
        }

        if(authType.intValue() == DeviceAuthTypeEnum.DAT_MONTH.getId().intValue()){ //按月购买
            if(quantity.intValue() >120){ //不能超过120月
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "最大购买月数不能超过120个月");
            }
        }else{ //按年购买
            if(quantity.intValue() >10){ //不能超过10年
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "最大购买年数不能超过10年");
            }
        }

        //保存到数据库当中的购买月数，按年买需要乘以12月
        Integer quantity_db = 0;

        //返回对象
        DeviceAmountVo deviceAmountVo = new DeviceAmountVo();

        //封装机器人授权信息
        List<DeviceAmountVo.DeviceProductAuth> deviceProductAuthList = new ArrayList<>();

        if(operType.intValue() == 1 ){ //添加机器人

            if(deviceTypeId.intValue() != DeviceTypeEnum.TIKTOK.getId().intValue()){
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "仅支持添加机器人移动端");
            }

            //设备id
            String deviceId = deviceAmountDto.getDeviceId();

            //购买产品
            DeviceProduct deviceProduct_add = deviceProductMapper.selectByCode(TiktokDeviceProductEnum.FD.getValue());
            if(deviceProduct_add == null){
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "系统未配置该产品功能");
            }

            //List<String> productCodeList = JSONObject.parseArray(deviceProduct_add.getCodes(), String.class);
            //从枚举中获取关联的产品
            TiktokDeviceProductEnum deviceProductEnum = TiktokDeviceProductEnum.getValue(deviceProduct_add.getCode());
            List<String> productCodeList = JSONObject.parseArray(deviceProductEnum.getCodes(), String.class);
            if(productCodeList == null || productCodeList.size() == 0){
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "系统全包套餐还没配置包含产品信息");
            }

            //查询all产品的价格
            DevicePrice devicePrice_all = devicePriceMapper.selectByAuthType(authType, TiktokDeviceProductEnum.FD.getValue(), DeviceTypeEnum.TIKTOK_VALUE);
            if(devicePrice_all == null){
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "系统还未配置所有产品的价格");
            }
            //all产品
            Double price_all = Tools.getDouble(devicePrice_all.getPrice());

            //分别查询ALL产品包含的产品的总价格
            Double price_total = 0.00D;
            for(String productCode : productCodeList){
                //查询产品价格
                DevicePrice devicePrice = devicePriceMapper.selectByAuthType(authType, productCode, DeviceTypeEnum.TIKTOK_VALUE);
                if(devicePrice == null){
                    throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "系统还未配置好产品的价格");
                }
                price_total = Math.add(price_total, Tools.getDouble(devicePrice.getPrice()));
            }

            //总单价的优惠
            Double price_discount = Math.sub(price_total, price_all);

            //当天时间
            Integer now = DateUtil.getNowTime();
            //总金额
            Double amount_totle = 0.00D;
            //新的到期时间
            Integer expired_time = 0;
            //本次授权开始时间默认为现在
            Integer begin_time = now;

            //设备号不为空，则开始时间为数据库中最早的授权时间
            if(StringUtils.isNotBlank(deviceId)){
                begin_time = deviceAuthService.selectEarliestAuthByDeviceIdAndProductCodeList(deviceId,productCodeList,now);
            }

            //到期时间
            if (authType.intValue() == DeviceAuthTypeEnum.DAT_MONTH.getId().intValue()) {//按月购买
                //新的到期时间=现在+月数*30天*24小时*3600秒
                expired_time = begin_time + quantity * 30 * 24 * 3600;
            }else{//按年购买
                //新的到期时间=现在+年数*12月*30天*24小时*3600秒
                expired_time = begin_time + quantity * 12 * 30 * 24 * 3600;
            }

            //单个机器人总金额=单价*购买时间数
            Double amount = Math.mul(Tools.getDouble(devicePrice_all.getPrice()), quantity);
            if(StringUtils.isBlank(deviceId)){
                //总金额累加
                amount_totle = Math.add(amount_totle, amount);
            }else{ //需要判断是否补差价
                //新增加时，只能买全包，计算是否需要补差价
                for (String productCode : productCodeList) {
                    //查询产品价格
                    DevicePrice devicePrice = devicePriceMapper.selectByAuthType(authType, productCode, DeviceTypeEnum.TIKTOK_VALUE);
                    if (devicePrice == null) {
                        throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请先设置抖音设备机器人手机端购买价格");
                    }
                    //产品单价
                    Double product_price = Tools.getDouble(devicePrice.getPrice());
                    //计算优惠后的产品单价 = 单价- 单价/总价 * 总优惠价
                    Double product_price_discount = Math.sub(product_price, Math.mul(Math.div(product_price, price_total), price_discount, 2));
                    //查询旧授权
                    DeviceAuth deviceAuth = deviceAuthMapper.selectByDeviceIdAndProductCode(deviceId, productCode);
                    //还未授权,不需要补差价
                    if (deviceAuth == null) {
                        //总金额累加
                        //amount_totle =  Math.add(amount_totle, amount);
                    } else { //授权存在，需判断授权的结束时间
                        //旧到期时间
                        Integer old_expireTime = Tools.getInteger(deviceAuth.getExpireTime());
                        //判断旧授权是否已经过期，
                        if (old_expireTime <= now) { //已经过期,不需要补差价
                            //总金额累加
                            //amount_totle = Math.add(amount_totle, amount);
                        } else if (old_expireTime > now && old_expireTime < expired_time) {//未过期，且小于授权到期时间，如果大于，则跳过不过授权
                            //需要补差价
                            Double differenceAmount = 0.00D;
                            //减去当前的时间，除以3600秒，再除以24小时取整，即是相差的天数
                            Double days = Math.div((old_expireTime - begin_time), 3600 *24,2 );
                            if (authType.intValue() == DeviceAuthTypeEnum.DAT_MONTH.getId()) {//按月购买的
                                differenceAmount = Math.mul(Math.div(product_price_discount, 30), days, 2);
                            } else {
                                differenceAmount = Math.mul(Math.div(product_price_discount, 360), days, 2);;
                            }
                            //单产品支付的金额
                            amount = Math.sub(amount, differenceAmount);
                        }
                    }
                }
                //总金额累加
                amount_totle = Math.add(amount_totle, amount);
            }
            deviceAmountVo.setAmountTotal(amount_totle);
        }else{ //购买授权
            //设备id
            List<Long> idList = deviceAmountDto.getIdList();
            if(idList == null || idList.size() == 0){
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请选择需要购买授权的机器人");
            }

            //购买产品
            String productCode_buy = deviceAmountDto.getProductCode();
            if(StringUtils.isBlank(productCode_buy)){
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请选择购买产品功能");
            }
            DeviceProduct deviceProduct_buy = deviceProductMapper.selectByCode(productCode_buy);
            if(deviceProduct_buy == null){
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "系统未配置该产品功能");
            }
            //List<String> productCodeList_buy = JSONObject.parseArray(deviceProduct_buy.getCodes(), String.class);
            //从枚举中获取关联的产品
            TiktokDeviceProductEnum deviceProductEnum = TiktokDeviceProductEnum.getValue(deviceProduct_buy.getCode());
            List<String> productCodeList_buy = JSONObject.parseArray(deviceProductEnum.getCodes(), String.class);
            if(productCodeList_buy == null || productCodeList_buy.size() == 0){
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "系统还没配置该产品功能信息");
            }

            //查询产品的总价格
            DevicePrice devicePrice_buy = devicePriceMapper.selectByAuthType(authType, productCode_buy, DeviceTypeEnum.TIKTOK_VALUE);
            if(devicePrice_buy == null){
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "系统还未配置产品的价格");
            }
            //all产品
            Double price_all = Tools.getDouble(devicePrice_buy.getPrice());
            //分别查询该产品包含的产品的总价格
            Double price_total = 0.00D;
            for(String productCode : productCodeList_buy){
                //查询产品价格
                DevicePrice devicePrice = devicePriceMapper.selectByAuthType(authType, productCode, DeviceTypeEnum.TIKTOK_VALUE);
                if(devicePrice == null){
                    throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "系统还未配置好产品的价格");
                }
                price_total = Math.add(price_total, Tools.getDouble(devicePrice.getPrice()));
            }
            //总单价的优惠
            Double price_discount = Math.sub(price_total, price_all);

            if(price_discount.doubleValue() < 0 ){
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "系统产品价格设置错误");
            }

            //当天时间
            Integer now = DateUtil.getNowTime();
            //总金额
            Double amount_totle = 0.00D;
            //新的到期时间
            Integer expired_time = 0;

            //循环批量操作的机器人
            for(Long deviceUniqueId : idList) {

                //查询机器人信息
                DeviceTiktokInfo deviceTiktokInfo = deviceTiktokInfoMapper.selectById(deviceUniqueId, deviceAmountDto.getMerId());
                if (deviceTiktokInfo == null) {
                    throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "选择的机器人不存在");
                }
                String deviceId = deviceTiktokInfo.getDeviceId();

                //本次授权开始时间默认为现在
                Integer begin_time = now;

                //查询该设备最早授权时间,如果不为空，则取最早授权时间为本次授权开始时间
                begin_time = deviceAuthService.selectEarliestAuthByDeviceIdAndProductCodeList(deviceId, productCodeList_buy, now);

                //选择全包套餐包时的到期时间，如果单个基础包购买，则另外判断到期时间
                if (authType.intValue() == DeviceAuthTypeEnum.DAT_MONTH.getId().intValue()) {//按月购买
                    //新的到期时间=现在+月数*30天*24小时*3600秒
                    expired_time = begin_time + quantity * 30 * 24 * 3600;
                    quantity_db = quantity;
                }else{//按年购买
                    //新的到期时间=现在+年数*12月*30天*24小时*3600秒
                    expired_time = begin_time + quantity * 12 * 30 * 24 * 3600;
                    quantity_db = quantity * 12;
                }

                //判断购买的产品类型（全包类型需要补差价）
                if (productCodeList_buy.size() == 1) { //单个基础包，则需重新设置到期时间，直接时间累加
                    //单个产品授权开始时间
                    Integer beginTime_one = 0;
                    //单个产品授权结束时间
                    Integer expireTime_one = 0;
                    //单个产品授权天数
                    Integer authDays_one = quantity_db * 30;
                    String productCode = productCodeList_buy.get(0);
                    DevicePrice devicePrice = devicePriceMapper.selectByAuthType(authType, productCode, DeviceTypeEnum.TIKTOK_VALUE);
                    if (devicePrice == null) {
                        throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请先设置机器人该端的购买价格");
                    }
                    //单个机器人总金额=单价*购买时间数
                    Double amount = Math.mul(Tools.getDouble(devicePrice.getPrice()), quantity);
                    //总金额累加
                    amount_totle = Math.add(amount_totle, amount);

                    //计算产品授权记录
                    //添加机器人授权表-如果没有则新增，有则修改
                    DeviceAuth deviceAuth = deviceAuthMapper.selectByDeviceIdAndProductCode(deviceId, productCode);
                    if(deviceAuth != null){//修改
                        //判断旧到期时间是否已经过期
                        Integer old_expireTime = Tools.getInteger(deviceAuth.getExpireTime());
                        if(old_expireTime <= now){//已经到期，则从今天开始算
                            beginTime_one = now;
                            expireTime_one = beginTime_one + quantity_db * 30 * 24 * 3600;
                        }else{
                            beginTime_one = old_expireTime;
                            expireTime_one = beginTime_one + quantity_db * 30 * 24 * 3600;
                        }
                    }else{
                        beginTime_one = now;
                        expireTime_one = beginTime_one + quantity_db * 30 * 24 * 3600;
                    }

                    //机器人redis缓存信息-产品授权
                    DeviceAmountVo.DeviceProductAuth deviceProductAuth = new DeviceAmountVo.DeviceProductAuth();
                    deviceProductAuth.setAuthDays(authDays_one);
                    deviceProductAuth.setExpireTime(expireTime_one);
                    deviceProductAuth.setProductCode(productCode);
                    deviceProductAuth.setProductName(DeviceProductKeyEnum.getDesc(productCode));
                    deviceProductAuthList.add(deviceProductAuth);
                } else { //全包产品
                    //单个机器人总金额=单价*购买时间数
                    Double amount = Math.mul(Tools.getDouble(devicePrice_buy.getPrice()), quantity);

                    for (String productCode : productCodeList_buy) {

                        //单个产品授权天数
                        Integer authDays_one = quantity_db * 30;

                        //查询产品价格
                        DevicePrice devicePrice = devicePriceMapper.selectByAuthType(authType, productCode, DeviceTypeEnum.TIKTOK_VALUE);
                        if (devicePrice == null) {
                            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请先设置抖音设备机器该端的购买价格");
                        }

                        //产品单价
                        Double product_price = devicePrice.getPrice();
                        //计算优惠后的产品单价 = 单价- 单价/总价 * 总优惠价
                        Double product_price_discount = Math.sub(product_price, Math.mul(Math.div(product_price, price_total), price_discount, 2));

                        //查询旧授权
                        DeviceAuth deviceAuth = deviceAuthMapper.selectByDeviceIdAndProductCode(deviceId, productCode);
                        //还未授权，不需要补差价
                        if (deviceAuth == null) {
                            //机器人redis缓存信息-产品授权
                            DeviceAmountVo.DeviceProductAuth deviceProductAuth = new DeviceAmountVo.DeviceProductAuth();
                            deviceProductAuth.setAuthDays(authDays_one);
                            deviceProductAuth.setExpireTime(expired_time);
                            deviceProductAuth.setProductCode(productCode);
                            deviceProductAuth.setProductName(DeviceProductKeyEnum.getDesc(productCode));
                            deviceProductAuthList.add(deviceProductAuth);
                        } else { //授权存在，需判断授权的结束时间
                            //旧到期时间
                            Integer old_expireTime = Tools.getInteger(deviceAuth.getExpireTime());
                            //判断旧授权是否已经过期，
                            if (old_expireTime <= now) { //已经过期，不需要补差价
                                //机器人redis缓存信息-产品授权
                                DeviceAmountVo.DeviceProductAuth deviceProductAuth = new DeviceAmountVo.DeviceProductAuth();
                                deviceProductAuth.setAuthDays(authDays_one);
                                deviceProductAuth.setExpireTime(expired_time);
                                deviceProductAuth.setProductCode(productCode);
                                deviceProductAuth.setProductName(DeviceProductKeyEnum.getDesc(productCode));
                                deviceProductAuthList.add(deviceProductAuth);
                            } else if (old_expireTime > now && old_expireTime < expired_time) {
                                //需要补差价
                                Double differenceAmount = 0.00D;
                                //减去当前的时间，除以3600秒，再除以24小时取整，即是相差的天数
                                Double days = Math.div((old_expireTime - begin_time), 3600 *24,2 );
                                if (authType.intValue() == DeviceAuthTypeEnum.DAT_MONTH.getId()) {//按月购买的
                                    differenceAmount = Math.mul(Math.div(product_price_discount, 30), days, 2);
                                } else {
                                    differenceAmount = Math.mul(Math.div(product_price_discount, 360), days, 2);
                                }
                                //单产品支付的金额
                                amount =  Math.sub(amount, differenceAmount);
                                //授权的天数
                                authDays_one = authDays_one - days.intValue();

                                //机器人redis缓存信息-产品授权
                                DeviceAmountVo.DeviceProductAuth deviceProductAuth = new DeviceAmountVo.DeviceProductAuth();
                                deviceProductAuth.setAuthDays(authDays_one);
                                deviceProductAuth.setExpireTime(expired_time);
                                deviceProductAuth.setProductCode(productCode);
                                deviceProductAuth.setProductName(DeviceProductKeyEnum.getDesc(productCode));
                                deviceProductAuthList.add(deviceProductAuth);
                            }else if(old_expireTime >= expired_time){
                                //需要补差价
                                Double differenceAmount = 0.00D;
                                //全额退款
                                if (authType.intValue() == DeviceAuthTypeEnum.DAT_MONTH.getId()) {//按月购买的
                                    differenceAmount = Math.mul(Math.div(product_price_discount, 30), authDays_one, 2);
                                } else {
                                    differenceAmount = Math.mul(Math.div(product_price_discount, 360), authDays_one, 2);
                                }
                                //单产品支付的金额
                                amount =  Math.sub(amount, differenceAmount);
                            }
                        }
                    }
                    //总金额累加
                    amount_totle = Math.add(amount_totle, amount);
                }
            }
            deviceAmountVo.setAmountTotal(amount_totle);
            deviceAmountVo.setDeviceProductAuthList(deviceProductAuthList);
        }
        return deviceAmountVo;
    }

    /**
     * 查询购买产品授权价格
     * @author liuqi
     * @date 2021/8/25 11:38
     * @param devicePriceDto
     */
    public DevicePriceVo getDevicePrice(DevicePriceDto devicePriceDto){

        //授权类型(1月卡;2年卡)
        Integer authType = devicePriceDto.getAuthType();
        if(authType == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入授权类型");
        }

        String productCode = devicePriceDto.getProductCode();
        if(StringUtils.isBlank(productCode)){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入产品编码");
        }

        //查询产品价格
        DevicePrice devicePrice = devicePriceMapper.selectByAuthType(authType, productCode, DeviceTypeEnum.TIKTOK_VALUE);
        if(devicePrice == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该产品还未设置价格");
        }

        DevicePriceVo devicePriceVo = new DevicePriceVo();
        devicePriceVo.setPrice(devicePrice.getPrice());

        return  devicePriceVo;
    }

    /**
     * 查询设备产品列表
     * @author liuqi
     * @date 2021/8/25 11:38
     * @param deviceProductQuery
     */
    public List<DeviceProductVo> deviceProductList(DeviceProductQuery deviceProductQuery){
        List<DeviceProductVo> deviceProductVoList = new ArrayList<>();

        TiktokDeviceProductEnum[] deviceProductEnums = TiktokDeviceProductEnum.values();
        if(deviceProductEnums != null && deviceProductEnums.length > 0){
            for (TiktokDeviceProductEnum deviceProductEnum : deviceProductEnums){
                DeviceProductVo deviceProductVo = new DeviceProductVo();
                DeviceProduct deviceProduct = deviceProductMapper.selectByCode(deviceProductEnum.getValue());
                if(deviceProduct != null){
                    BeanUtils.copyProperties(deviceProduct, deviceProductVo);
                }

                deviceProductVo.setName(deviceProductEnum.getDesc());

                if(StringUtils.isNotBlank(deviceProductEnum.getCodes())){
                    deviceProductVo.setCodeList(JSONObject.parseArray(deviceProductEnum.getCodes(), String.class));
                }
                deviceProductVoList.add(deviceProductVo);
            }
        }
        return deviceProductVoList;
    }

    /**
     * 转移授权时间
     * @author liuqi
     * @date 2021/8/25 11:38
     * @param tranferAuthTimeDto
     */
    @Transactional
    public void transferAuthTime(TranferAuthTimeDto tranferAuthTimeDto){

        String trandeNo = Tools.getCurrentTimeByFormat("yyyyMMdd") + IdWorker.getIdStr();

        int now = DateUtil.getNowTime();
        Long merId = tranferAuthTimeDto.getMerId();

        Long id = tranferAuthTimeDto.getId();
        Long transferIdForAuthTime = tranferAuthTimeDto.getTransferIdForAuthTime();
        Long transferIdForUserAndOrder = tranferAuthTimeDto.getTransferIdForUserAndOrder();
        Integer transferDataFlag = tranferAuthTimeDto.getTransferDataFlag();

        if(id == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请选择被转移机器人");
        }
        if(transferIdForAuthTime == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请选择新转移授权时间机器人");
        }

        if(id.longValue() == transferIdForAuthTime.longValue()){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "新转移机器人不能是自己本身");
        }

        DeviceTiktokInfo deviceTiktokInfo = deviceTiktokInfoMapper.selectById(id, tranferAuthTimeDto.getMerId());
        if(deviceTiktokInfo == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "被转移机器人不存在");
        }

        DeviceTiktokInfo deviceTiktokInfo_transferForAuthTime = deviceTiktokInfoMapper.selectById(transferIdForAuthTime, tranferAuthTimeDto.getMerId());
        if(deviceTiktokInfo_transferForAuthTime == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "新转移授权时间机器人不存在");
        }

        //查询被转机器人的授权记录
        //授权信息
        List<DeviceAuthVo> deviceAuthVoList = new ArrayList<>();
        DeviceAuthQuery deviceAuthQuer = new DeviceAuthQuery();
        deviceAuthQuer.setDeviceId(deviceTiktokInfo.getDeviceId());
        List<DeviceAuth> deviceAuthList =  deviceAuthMapper.findByList(deviceAuthQuer);
        if(deviceAuthList != null && deviceAuthList.size() > 0) {
            for (DeviceAuth deviceAuth : deviceAuthList) {
                //到期时间
                Integer expiretime = Tools.getInteger(deviceAuth.getExpireTime());
                //计算出将要转移的时间(减去5天试用期)
                int transferTime = expiretime.intValue() - now - 5*24*3600;
                if(expiretime.intValue() > now && transferTime > 0){//未到期有授权的才处理

                    //先将被转机器人的授权修改成现在到期
                    deviceAuth.setExpireTime(now);
                    deviceAuthMapper.updateById(deviceAuth);

                    //添加授权记录
                    DeviceAuthDetail deviceAuthDetail = new DeviceAuthDetail();
                    deviceAuthDetail.setId(IdWorker.getId());
                    deviceAuthDetail.setMerId(merId);
                    deviceAuthDetail.setDeviceUniqueId(deviceTiktokInfo.getId());
                    deviceAuthDetail.setDeviceId(deviceAuth.getDeviceId());
                    deviceAuthDetail.setDeviceType(deviceAuth.getDeviceType());
                    deviceAuthDetail.setDeviceTypeId(deviceAuth.getDeviceTypeId());
                    deviceAuthDetail.setProductCode(deviceAuth.getProductCode());
                    deviceAuthDetail.setAuthType(DeviceAuthTypeEnum.DAT_TRANSFER.getId());
                    deviceAuthDetail.setQuantity(0);
                    deviceAuthDetail.setPayTime(now);
                    deviceAuthDetail.setPayType(PaymentTypeEnum.PAY_FREE.getId());
                    deviceAuthDetail.setTradeno(trandeNo);
                    deviceAuthDetail.setRemark("机器人转移（转出），新机器人微信id:="+deviceTiktokInfo_transferForAuthTime.getDeviceId()+";旧授权时间:=" + expiretime+";转移时间:=" +transferTime);
                    deviceAuthDetail.setCreateTime(now);
                    deviceAuthDetail.setUpdateTime(now);
                    deviceAuthDetail.setAmount(0.00);
                    deviceAuthDetail.setBeginTime(now);
                    deviceAuthDetail.setExpireTime(deviceAuth.getExpireTime());
                    //插入授权数据明细
                    deviceAuthDetailMapper.insert(deviceAuthDetail);


                    //然后将新转移机器人的授权时间延长
                    DeviceAuth deviceAuth_transfer = deviceAuthMapper.selectByDeviceIdAndProductCode(deviceTiktokInfo_transferForAuthTime.getDeviceId(), deviceAuth.getProductCode());
                    //先判断存不存在，不存在则新增，存在则延迟时间
                    if(deviceAuth_transfer != null){ //授权存在，还需要判断授权时间是否过去
                        Integer expireTime_transfer = Tools.getInteger(deviceAuth_transfer.getExpireTime());

                        //未过期，则直接添加授权时间插
                        if(expireTime_transfer-now > 0){
                            deviceAuth_transfer.setExpireTime(expireTime_transfer.intValue() + transferTime);
                            deviceAuth_transfer.setUpdateTime(now);
                            deviceAuthMapper.updateById(deviceAuth_transfer);

                            //添加授权记录
                            DeviceAuthDetail deviceAuthDetail_transfer = new DeviceAuthDetail();
                            deviceAuthDetail_transfer.setId(IdWorker.getId());
                            deviceAuthDetail_transfer.setMerId(merId);
                            deviceAuthDetail_transfer.setDeviceUniqueId(deviceAuth_transfer.getId());
                            deviceAuthDetail_transfer.setDeviceId(deviceAuth_transfer.getDeviceId());
                            deviceAuthDetail_transfer.setDeviceType(deviceAuth_transfer.getDeviceType());
                            deviceAuthDetail_transfer.setDeviceTypeId(deviceAuth_transfer.getDeviceTypeId());
                            deviceAuthDetail_transfer.setProductCode(deviceAuth_transfer.getProductCode());
                            deviceAuthDetail_transfer.setAuthType(DeviceAuthTypeEnum.DAT_TRANSFER.getId());
                            deviceAuthDetail_transfer.setQuantity(0);
                            deviceAuthDetail_transfer.setPayTime(now);
                            deviceAuthDetail_transfer.setPayType(PaymentTypeEnum.PAY_FREE.getId());
                            deviceAuthDetail_transfer.setTradeno(trandeNo);
                            deviceAuthDetail_transfer.setRemark("机器人转移（转入），旧机器人微信id:="+deviceTiktokInfo.getDeviceId()+";旧授权时间:=" + expireTime_transfer+";转移时间:=" +transferTime);
                            deviceAuthDetail_transfer.setCreateTime(now);
                            deviceAuthDetail_transfer.setUpdateTime(now);
                            deviceAuthDetail_transfer.setAmount(0.00);
                            deviceAuthDetail_transfer.setBeginTime(now);
                            deviceAuthDetail_transfer.setExpireTime(deviceAuth_transfer.getExpireTime());
                            //插入授权数据明细
                            deviceAuthDetailMapper.insert(deviceAuthDetail_transfer);

                        }else{//已过期，则直接将被转移机器人的授权到期时间减去5天（试用期）替换新机器人的授权到期时间
                            deviceAuth_transfer.setExpireTime(expiretime - 5*24*3600);
                            deviceAuth_transfer.setUpdateTime(now);
                            deviceAuthMapper.updateById(deviceAuth_transfer);

                            //添加授权记录
                            DeviceAuthDetail deviceAuthDetail_transfer = new DeviceAuthDetail();
                            deviceAuthDetail_transfer.setId(IdWorker.getId());
                            deviceAuthDetail_transfer.setMerId(merId);
                            deviceAuthDetail_transfer.setDeviceUniqueId(deviceAuth_transfer.getId());
                            deviceAuthDetail_transfer.setDeviceId(deviceAuth_transfer.getDeviceId());
                            deviceAuthDetail_transfer.setDeviceType(deviceAuth_transfer.getDeviceType());
                            deviceAuthDetail_transfer.setDeviceTypeId(deviceAuth_transfer.getDeviceTypeId());
                            deviceAuthDetail_transfer.setProductCode(deviceAuth_transfer.getProductCode());
                            deviceAuthDetail_transfer.setAuthType(DeviceAuthTypeEnum.DAT_TRANSFER.getId());
                            deviceAuthDetail_transfer.setQuantity(0);
                            deviceAuthDetail_transfer.setPayTime(now);
                            deviceAuthDetail_transfer.setPayType(PaymentTypeEnum.PAY_FREE.getId());
                            deviceAuthDetail_transfer.setTradeno(trandeNo);
                            deviceAuthDetail_transfer.setRemark("机器人转移，旧机器人微信id:="+deviceTiktokInfo.getDeviceId()+";旧授权时间:=" + expireTime_transfer+";转移时间:=" +transferTime);
                            deviceAuthDetail_transfer.setCreateTime(now);
                            deviceAuthDetail_transfer.setUpdateTime(now);
                            deviceAuthDetail_transfer.setAmount(0.00);
                            deviceAuthDetail_transfer.setBeginTime(now);
                            deviceAuthDetail_transfer.setExpireTime(deviceAuth_transfer.getExpireTime());
                            //插入授权数据明细
                            deviceAuthDetailMapper.insert(deviceAuthDetail_transfer);
                        }
                    }else{ //不存在
                        deviceAuth_transfer = new DeviceAuth();
                        deviceAuth_transfer.setId(IdWorker.getId());
                        deviceAuth_transfer.setDeviceId(deviceTiktokInfo_transferForAuthTime.getDeviceId());
                        deviceAuth_transfer.setDeviceUniqueId(deviceTiktokInfo_transferForAuthTime.getId());
                        deviceAuth_transfer.setDeviceType(DeviceTypeEnum.TIKTOK.getKey());
                        deviceAuth_transfer.setDeviceTypeId(DeviceTypeEnum.TIKTOK.getId());
                        deviceAuth_transfer.setProductCode(deviceAuth.getProductCode());
                        deviceAuth_transfer.setAuthType(DeviceAuthTypeEnum.DAT_TRANSFER.getId());
                        //将被转移机器人的授权到期时间减去5天（试用期）替换新机器人的授权到期时间
                        deviceAuth_transfer.setExpireTime(expiretime - 5*24*3600);
                        deviceAuth_transfer.setCreateTime(now);
                        deviceAuth_transfer.setUpdateTime(now);
                        deviceAuthMapper.insertSelective(deviceAuth_transfer);

                        //封装产品授权记录
                        DeviceAuthDetail deviceAuthDetail_transfer = new DeviceAuthDetail();
                        deviceAuthDetail_transfer.setId(IdWorker.getId());
                        deviceAuthDetail_transfer.setMerId(merId);
                        deviceAuthDetail_transfer.setDeviceUniqueId(deviceAuth_transfer.getId());
                        deviceAuthDetail_transfer.setDeviceId(deviceAuth_transfer.getDeviceId());
                        deviceAuthDetail_transfer.setDeviceType(deviceAuth_transfer.getDeviceType());
                        deviceAuthDetail_transfer.setDeviceTypeId(deviceAuth_transfer.getDeviceTypeId());
                        deviceAuthDetail_transfer.setProductCode(deviceAuth_transfer.getProductCode());
                        deviceAuthDetail_transfer.setAuthType(DeviceAuthTypeEnum.DAT_TRANSFER.getId());
                        deviceAuthDetail_transfer.setQuantity(0);
                        deviceAuthDetail_transfer.setPayTime(now);
                        deviceAuthDetail_transfer.setPayType(PaymentTypeEnum.PAY_FREE.getId());
                        deviceAuthDetail_transfer.setTradeno(trandeNo);
                        deviceAuthDetail_transfer.setRemark("机器人转移，旧机器人微信id:"+deviceTiktokInfo.getDeviceId()+";旧授权时间:=0;转移时间:=" +transferTime);
                        deviceAuthDetail_transfer.setCreateTime(now);
                        deviceAuthDetail_transfer.setUpdateTime(now);
                        deviceAuthDetail_transfer.setAmount(0.00);
                        deviceAuthDetail_transfer.setBeginTime(now);
                        deviceAuthDetail_transfer.setExpireTime(deviceAuth_transfer.getExpireTime());
                        //插入授权数据明细
                        deviceAuthDetailMapper.insert(deviceAuthDetail_transfer);
                    }
                }
            }
        }

        //转移会员和订单
        if(transferDataFlag != null && transferDataFlag.intValue() == 1){
            if(transferIdForUserAndOrder == null){
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请选择新转移会员订单机器人");
            }

            DeviceTiktokInfo deviceTiktokInfo_transferForUserAndOrder = deviceTiktokInfoMapper.selectById(transferIdForUserAndOrder, tranferAuthTimeDto.getMerId());
            if(deviceTiktokInfo_transferForUserAndOrder == null){
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "新转移会员订单机器人不存在");
            }

            if(id.longValue() == transferIdForUserAndOrder.longValue()){
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "新转移机器人不能是自己本身");
            }

            ConfigPlan configPlan_self = configPlanMapper.selectById(deviceTiktokInfo.getConfigId(), deviceTiktokInfo.getMerId());
            if(configPlan_self == null){
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "被转移的机器人配置方案不存在");
            }

            ConfigPlan configPlan_transferForUserAndOrder = configPlanMapper.selectById(deviceTiktokInfo_transferForUserAndOrder.getConfigId(), deviceTiktokInfo_transferForUserAndOrder.getMerId());
            if(configPlan_transferForUserAndOrder == null){
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "新转移会员订单的机器人配置方案不存在");
            }

            if(Tools.getLong(configPlan_self.getUserTypeGroupId()).longValue() != Tools.getLong(configPlan_transferForUserAndOrder.getUserTypeGroupId()).longValue()){
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "新转移会员订单的机器人的会员类型组与旧的不一样");
            }

            //转移会员
            wechatUserMapper.batchUpdateDeviceInfo(id, transferIdForUserAndOrder, merId);
            //转移淘宝订单
            tbOrderMapper.batchUpdateDeviceInfo(id, transferIdForUserAndOrder, merId);
            //转移京东订单
            jdOrderMapper.batchUpdateDeviceInfo(id, transferIdForUserAndOrder, merId);
            //转移拼多多订单
            pddOrderMapper.batchUpdateDeviceInfo(id, transferIdForUserAndOrder, merId);
            //转移唯品会订单
            vphOrderMapper.batchUpdateDeviceInfo(id, transferIdForUserAndOrder, merId);
            //转移美团订单
            mtOrderMapper.batchUpdateDeviceInfo(id, transferIdForUserAndOrder, merId);
            //转移抖音订单
            dyOrderMapper.batchUpdateDeviceInfo(id, transferIdForUserAndOrder, merId);

        }
    }

    /**
     * 删除机器人且转移数据
     * @author liuqi
     * @date 2021/8/25 11:38
     * @param delAndTransferDataDto
     */
    @Transactional
    public void delAndTransferData(DelAndTransferDataDto delAndTransferDataDto){

        int now = DateUtil.getNowTime();
        Long merId = delAndTransferDataDto.getMerId();

        Long id = delAndTransferDataDto.getId();
        Long transferId = delAndTransferDataDto.getTransferId();

        if(id == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请选择将要删除的机器人");
        }
        DeviceTiktokInfo deviceTiktokInfo = deviceTiktokInfoMapper.selectById(id, delAndTransferDataDto.getMerId());
        if(deviceTiktokInfo == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "将要删除的机器人不存在");
        }

        //需要转移机器人，则必须要选择转移的新机器人
        if(transferId != null){
            if(id.longValue() == transferId.longValue()){
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "新转移机器人不能是自己本身");
            }
            DeviceTiktokInfo deviceTiktokInfo_transfer = deviceTiktokInfoMapper.selectById(transferId, delAndTransferDataDto.getMerId());
            if(deviceTiktokInfo_transfer == null){
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "新转移机器人不存在");
            }

            ConfigPlan configPlan_self = configPlanMapper.selectById(deviceTiktokInfo.getConfigId(), deviceTiktokInfo.getMerId());
            if(configPlan_self == null){
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "被转移的机器人配置方案不存在");
            }

            ConfigPlan configPlan_transfer = configPlanMapper.selectById(deviceTiktokInfo_transfer.getConfigId(), deviceTiktokInfo_transfer.getMerId());
            if(configPlan_transfer == null){
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "新转移会员订单的机器人配置方案不存在");
            }

            if(Tools.getLong(configPlan_self.getUserTypeGroupId()).longValue() != Tools.getLong(configPlan_transfer.getUserTypeGroupId()).longValue()){
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "新转移会员订单的机器人的会员类型组与旧的不一样");
            }

            //转移会员
            wechatUserMapper.batchUpdateDeviceInfo(id, transferId, merId);
            //转移淘宝订单
            tbOrderMapper.batchUpdateDeviceInfo(id, transferId, merId);
            //转移京东订单
            jdOrderMapper.batchUpdateDeviceInfo(id, transferId, merId);
            //转移拼多多订单
            pddOrderMapper.batchUpdateDeviceInfo(id, transferId, merId);
            //转移唯品会订单
            vphOrderMapper.batchUpdateDeviceInfo(id, transferId, merId);
            //转移美团订单
            mtOrderMapper.batchUpdateDeviceInfo(id, transferId, merId);
            //转移抖音订单
            dyOrderMapper.batchUpdateDeviceInfo(id, transferId, merId);
        }

        //删除该机器人
        deviceTiktokInfoMapper.deleteById(id, delAndTransferDataDto.getMerId());
        //清除机器人所属运营商缓存
        redisTemplate.delete(String.format(RedisCacheKeyEnum.DEVICE_MERCHANT.getKey(), deviceTiktokInfo.getDeviceId()));
        //删除机器人移动端缓存
        redisTemplate.delete(String.format(RedisCacheKeyEnum.DEVICE_INFO_TIKTOK.getKey(), deviceTiktokInfo.getId()));
    }

    /**
     * 刷新在线状态
     * @author liuqi
     * @date 2021/8/25 11:38
     * @param merId
     */
    public void refreshOnlineStatus(Long merId){
        if(merId == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请先登录");
        }
        DeviceTiktokInfoQuery deviceTiktokInfoQuery = new DeviceTiktokInfoQuery();
        deviceTiktokInfoQuery.setMerId(merId);
        List<DeviceTiktokInfo> deviceTiktokInfoList =  deviceTiktokInfoMapper.findByList(deviceTiktokInfoQuery);
        if(deviceTiktokInfoList != null && deviceTiktokInfoList.size() > 0){
            for (DeviceTiktokInfo deviceTiktokInfo : deviceTiktokInfoList){
                //默认离线
                deviceTiktokInfo.setMobileStatus(Tools.getInteger(deviceTiktokInfo.getMobileStatus()));
                try {
                    //移动端
                    Object object_mobile = redisTemplate.opsForValue().get(String.format(RedisCacheKeyEnum.DEVICE_INFO_TIKTOK.getKey(), deviceTiktokInfo.getId()));
                    if(object_mobile != null) {
                        DeviceInfoTiktokCacheDto deviceInfoTiktokCacheDto = JSONObject.parseObject(String.valueOf(object_mobile), DeviceInfoTiktokCacheDto.class);
                        //手机端抖音设备信息不为空
                        if (deviceInfoTiktokCacheDto != null) {
                            //获取最新心跳时间
                            Integer lastHeartBeatTime = deviceInfoTiktokCacheDto.getLastHeartBeatTime();
                            if (lastHeartBeatTime != null) {
                                //判断在线（少于5分钟表示在线）
                                if (DateUtil.getNowTime() - lastHeartBeatTime < Const.Device.HEART_BEAT_OFF_LINE_TIME) {
                                    deviceTiktokInfo.setMobileStatus(1); //在线
                                } else {
                                    deviceTiktokInfo.setMobileStatus(0); //离线
                                }
                            }
                        }
                    }
                }catch (Exception e){}

                deviceTiktokInfoMapper.updateOnlineStatus(deviceTiktokInfo);
            }
        }
    }

    /**
     * 查询抖音设备机器人列表
     * @author liuqi
     * @date 2021/8/13 11:38
     * @param deviceTiktokInfoQuery
     * @return null
     */
    public List<DeviceTiktokInfoVo> findDeviceTiktokInfoSelect(DeviceTiktokInfoQuery deviceTiktokInfoQuery){

        //手动处理机器人分页查询-如果是机器人昵称，则按照中文gbk排序
        List<OrderItem> orderItemList = deviceTiktokInfoQuery.getOrderItemList();
        if(orderItemList != null && orderItemList.size() > 0){
            for (OrderItem orderItem :orderItemList){
                if("deviceName".equals(orderItem.getColumn())){
                    orderItem.setColumn(" convert( " + orderItem.getColumn() + " using gbk) ");
                }
            }
        }

        //新建返回到页面的LIST对象
        List<DeviceTiktokInfoVo> deviceTiktokInfoPageVoList = new ArrayList<>();

        ArrayList<DeviceTiktokInfo> deviceTiktokInfoList =  deviceTiktokInfoMapper.findByList(deviceTiktokInfoQuery);
        if(deviceTiktokInfoList != null && deviceTiktokInfoList.size() > 0){
            for (DeviceTiktokInfo deviceTiktokInfo : deviceTiktokInfoList){
                DeviceTiktokInfoVo deviceTiktokInfoPageVo = new DeviceTiktokInfoVo();
                BeanUtils.copyProperties(deviceTiktokInfo, deviceTiktokInfoPageVo);

                //机器人分组
                DeviceGroup deviceGroup = deviceGroupMapper.selectById(deviceTiktokInfo.getGroupId(), deviceTiktokInfo.getMerId());
                if(deviceGroup != null){
                    deviceTiktokInfoPageVo.setGroupName(deviceGroup.getName());
                }
                //获取配置方案信息
                ConfigPlan configPlan = configPlanMapper.selectById(deviceTiktokInfo.getConfigId(), deviceTiktokInfo.getMerId());
                if(configPlan != null){
                    deviceTiktokInfoPageVo.setConfigName(configPlan.getName());
                }
                deviceTiktokInfoPageVoList.add(deviceTiktokInfoPageVo);
            }
        }

        return deviceTiktokInfoPageVoList;
    }

    /**
     * 更新手机版
     * @author liuqi
     * @date 2021/8/13 11:38
     * @param deviceTiktokInfoIdDto
     * @return null
     */
    public void updateMobileClientSoft(DeviceTiktokInfoIdDto deviceTiktokInfoIdDto){
        if(deviceTiktokInfoIdDto.getId() == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入id参数");
        }

        DeviceTiktokInfo deviceTiktokInfo = deviceTiktokInfoMapper.selectById(deviceTiktokInfoIdDto.getId(), deviceTiktokInfoIdDto.getMerId());

        if(deviceTiktokInfo == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该机器人不存在");
        }

        //从缓存中换取抖音设备移动端信息
        Object object_mobile = redisTemplate.opsForValue().get(String.format(RedisCacheKeyEnum.DEVICE_INFO_TIKTOK.getKey(), deviceTiktokInfo.getId()));
        DeviceInfoTiktokCacheDto deviceInfoTiktokCacheDto = JSONObject.parseObject(String.valueOf(object_mobile), DeviceInfoTiktokCacheDto.class);

        //移动端抖音设备信息不为空
        if(deviceInfoTiktokCacheDto == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "移动端机器人还未曾登录过，不能更新版本");
        }

        //更新客户端版本状态(0-无更新；1-有更新；2-更新中; 3-更新失败(当状态为2时，验证更新时间是否超过5分钟，超过就更新失败)")
        Integer updateClientVersionStatus = deviceInfoTiktokCacheDto.getUpdateClientVersionStatus();
        Integer updateClientVersionTime = deviceInfoTiktokCacheDto.getUpdateClientVersionTime();
        if(updateClientVersionStatus != null && updateClientVersionStatus.intValue() == 2){
            if(DateUtil.getNowTime() - updateClientVersionTime < Const.Device.UPDATE_VERSION_VALIDITY_TIME){
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "机器人版本正在更新中 ，请稍后再试");
            }
        }

//        DeviceVersion deviceVersion = deviceVersionMapper.selectByTypeId(DeviceTypeEnum.TIKTOK.getId());
//        if(deviceVersion == null){
//            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "机器人最新版本为空");
//        }

        //从缓存中获取版本移动端版本信息
        Object object_mobile_version = redisTemplate.opsForValue().get(RedisCacheKeyEnum.MOBILE_APP_UPDATE_INFO.getKey());
        if(object_mobile_version == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "手机端软件版本信息未设置");
        }

        JSONObject jsonObject = JSONObject.parseObject(object_mobile_version.toString());
        if(jsonObject == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "手机端软件版本信息格式错误");
        }

        //软件版本号
        Integer verNumber = Tools.getInteger(jsonObject.getInteger("verNumber"));
        //软件版本名称
        String version = Tools.getStr(jsonObject.getString("version"));
        //包名称
        String packageName = Tools.getStr(jsonObject.getString("packageName"));
        //软件包URL地址
        String packageUrl = Tools.getStr(jsonObject.getString("packageUrl"));

        //发送微服务，通知终端
        MsgDto<UpdateAndroidAppDto> msgDto = new MsgDto<>();
        UpdateAndroidAppDto updateAndroidAppDto = new UpdateAndroidAppDto();
        msgDto.setContent(updateAndroidAppDto);
        msgDto.setId(IdWorker.getId());
        msgDto.setDeviceType(deviceTiktokInfo.getRecvmsgType());
        msgDto.setDeviceUniqueId(deviceTiktokInfo.getId());
        msgDto.setMerId(deviceTiktokInfo.getMerId());
        msgDto.setMsgType(MessageFuncEnum.UPDATE_ANDROID_APP.getValue());
        //封装参数对象
        updateAndroidAppDto.setWechatId(deviceTiktokInfo.getDeviceId());
        updateAndroidAppDto.setImei(deviceTiktokInfo.getDeviceId());
        updateAndroidAppDto.setVerNumber(verNumber);
        updateAndroidAppDto.setVersion(version);
        updateAndroidAppDto.setPackageName(packageName);
        updateAndroidAppDto.setPackageUrl(packageUrl);
        UzaiRespVo<Object> uzaiRespVo =  uzaiImClientFeignService.androidAppUpdate(msgDto);
        logger.info("---调用安卓APP版本更新接口----para={},result={}", JSONObject.toJSONString(msgDto), JSONObject.toJSONString(uzaiRespVo));

        if(uzaiRespVo != null && uzaiRespVo.getCode() == 200){
            //修改Redis状态
            deviceInfoTiktokCacheDto.setUpdateClientVersionStatus(2);
            deviceInfoTiktokCacheDto.setUpdateClientVersionTime(DateUtil.getNowTime());
            redisTemplate.opsForValue().set(String.format(RedisCacheKeyEnum.DEVICE_INFO_TIKTOK.getKey(), deviceTiktokInfo.getId()), Tools.getStrEmpty(JSONObject.toJSONString(deviceInfoTiktokCacheDto)));
        }

    }

    /**
     * 批量更新手机版
     * @author liuqi
     * @date 2021/8/13 11:38
     * @param deviceTiktokInfoIdListDto
     * @return null
     */
    public void batchUpdateMobileClientSoft(DeviceTiktokInfoIdListDto deviceTiktokInfoIdListDto){

        List<Long> idList = deviceTiktokInfoIdListDto.getIdList();

        if(idList == null || idList.size() == 0){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入id参数");
        }

        for (Long id : idList){
            DeviceTiktokInfo deviceTiktokInfo = deviceTiktokInfoMapper.selectById(id, deviceTiktokInfoIdListDto.getMerId());
            if(deviceTiktokInfo == null){
                continue;
            }

            //从缓存中换取抖音设备手机版端信息
            Object object_mobile = redisTemplate.opsForValue().get(String.format(RedisCacheKeyEnum.DEVICE_INFO_TIKTOK.getKey(), deviceTiktokInfo.getId()));
            DeviceInfoTiktokCacheDto deviceInfoTiktokCacheDto = JSONObject.parseObject(String.valueOf(object_mobile), DeviceInfoTiktokCacheDto.class);

            //手机版抖音设备信息不为空
            if(deviceInfoTiktokCacheDto == null){
                continue;
            }

            //更新客户端版本状态(0-无更新；1-有更新；2-更新中; 3-更新失败(当状态为2时，验证更新时间是否超过5分钟，超过就更新失败)")
            Integer updateClientVersionStatus = deviceInfoTiktokCacheDto.getUpdateClientVersionStatus();
            Integer updateClientVersionTime = deviceInfoTiktokCacheDto.getUpdateClientVersionTime();
            if(updateClientVersionStatus != null && updateClientVersionStatus.intValue() == 2){
                if(DateUtil.getNowTime() - updateClientVersionTime < Const.Device.UPDATE_VERSION_VALIDITY_TIME){
                    continue;
                }
            }

//            DeviceVersion deviceVersion = deviceVersionMapper.selectByTypeId(DeviceTypeEnum.TIKTOK.getId());
//            if(deviceVersion == null){
//                continue;
//            }

            //调用微服务通知移动端APP更新
            try {
                //从缓存中获取版本移动端版本信息
                Object object_mobile_version = redisTemplate.opsForValue().get(RedisCacheKeyEnum.MOBILE_APP_UPDATE_INFO.getKey());
                if(object_mobile_version == null){
                    throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "手机端软件版本信息未设置");
                }

                JSONObject jsonObject = JSONObject.parseObject(object_mobile_version.toString());
                if(jsonObject == null){
                    throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "手机端软件版本信息格式错误");
                }

                //软件版本号
                Integer verNumber = Tools.getInteger(jsonObject.getInteger("verNumber"));
                //软件版本名称
                String version = Tools.getStr(jsonObject.getString("version"));
                //包名称
                String packageName = Tools.getStr(jsonObject.getString("packageName"));
                //软件包URL地址
                String packageUrl = Tools.getStr(jsonObject.getString("packageUrl"));

                //发送微服务，通知终端
                MsgDto<UpdateAndroidAppDto> msgDto = new MsgDto<>();
                UpdateAndroidAppDto updateAndroidAppDto = new UpdateAndroidAppDto();
                msgDto.setContent(updateAndroidAppDto);
                msgDto.setId(IdWorker.getId());
                msgDto.setDeviceType(deviceTiktokInfo.getRecvmsgType());
                msgDto.setDeviceUniqueId(deviceTiktokInfo.getId());
                msgDto.setMerId(deviceTiktokInfo.getMerId());
                msgDto.setMsgType(MessageFuncEnum.UPDATE_ANDROID_APP.getValue());
                //封装参数对象
                updateAndroidAppDto.setWechatId(deviceTiktokInfo.getDeviceId());
                updateAndroidAppDto.setImei(deviceTiktokInfo.getDeviceId());
                updateAndroidAppDto.setVerNumber(verNumber);
                updateAndroidAppDto.setVersion(version);
                updateAndroidAppDto.setPackageName(packageName);
                updateAndroidAppDto.setPackageUrl(packageUrl);
                UzaiRespVo<Object> uzaiRespVo =  uzaiImClientFeignService.androidAppUpdate(msgDto);
                logger.info("---调用安卓APP版本更新接口----para={},result={}", JSONObject.toJSONString(msgDto), JSONObject.toJSONString(uzaiRespVo));

                if (uzaiRespVo != null && uzaiRespVo.getCode() == 200){
                    //修改Redis状态
                    deviceInfoTiktokCacheDto.setUpdateClientVersionStatus(2);
                    deviceInfoTiktokCacheDto.setUpdateClientVersionTime(DateUtil.getNowTime());
                    redisTemplate.opsForValue().set(String.format(RedisCacheKeyEnum.DEVICE_INFO_TIKTOK.getKey(), deviceTiktokInfo.getId()), Tools.getStrEmpty(JSONObject.toJSONString(deviceInfoTiktokCacheDto)));
                }
            }catch(Exception e) {
            }
        }
    }

    /**
     * 增加试用期授权
     * @author liuqi
     * @date 2021/8/13 11:38
     * @param deviceTiktokInfoAddProbationAuth
     * @return null
     */
    @Transactional
    public void addProbationAuth(DeviceTiktokInfoAddProbationAuth deviceTiktokInfoAddProbationAuth){

        Long merId = deviceTiktokInfoAddProbationAuth.getMerId();

        if(merId == null
                ||deviceTiktokInfoAddProbationAuth.getId() == null
                || StringUtils.isBlank(deviceTiktokInfoAddProbationAuth.getProductCode())){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "参数不能为空");
        }

        DeviceTiktokInfo deviceTiktokInfo = deviceTiktokInfoMapper.selectById(deviceTiktokInfoAddProbationAuth.getId(), deviceTiktokInfoAddProbationAuth.getMerId());
        if(deviceTiktokInfo == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该机器人唯一id不存在");
        }

        if(TiktokDeviceProductEnum.FD.getValue().equals(deviceTiktokInfoAddProbationAuth.getProductCode())){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "目前还未支持增加此产品试用期授权");
        }

        TiktokDeviceProductEnum deviceProductEnum = TiktokDeviceProductEnum.getValue(deviceTiktokInfoAddProbationAuth.getProductCode());

        if(deviceProductEnum == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该产品不存在");
        }

        List<String> productCodeList = JSONObject.parseArray(deviceProductEnum.getCodes(), String.class);
        if(productCodeList == null || productCodeList.size() == 0){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "系统未配置该产品信息");
        }

        //业务编码
        String trandeNo = Tools.getCurrentTimeByFormat("yyyyMMdd") + IdWorker.getIdStr();

        //当前时间
        int now = DateUtil.getNowTime();
        //产品到期时间=当前时间+5天
        int expired_time = now + Const.Device.DEVICE_DAT_FREE_DURATION * 24 * 3600;

        //新增加时，只能买全包，计算是否需要补差价
        for (String productCode : productCodeList) {
            DeviceAuth deviceAuth_old = deviceAuthMapper.selectByDeviceIdAndProductCode(deviceTiktokInfo.getDeviceId(), productCode);
            if(deviceAuth_old != null){
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该产品已经有授权记录，不能增加试用期授权");
            }

            //添加机器人授权表
            DeviceAuth deviceAuth = new DeviceAuth();
            deviceAuth.setId(IdWorker.getId());
            deviceAuth.setDeviceId(deviceTiktokInfo.getDeviceId());
            deviceAuth.setDeviceUniqueId(deviceTiktokInfo.getId());
            deviceAuth.setDeviceType(DeviceTypeEnum.TIKTOK.getKey());
            deviceAuth.setDeviceTypeId(DeviceTypeEnum.TIKTOK.getId());
            deviceAuth.setAuthType(DeviceAuthTypeEnum.DAT_FREE.getId().intValue());
            deviceAuth.setProductCode(productCode);
            //新授权，到期时间从今天开始算
            deviceAuth.setExpireTime(expired_time);
            deviceAuth.setCreateTime(now);
            deviceAuth.setUpdateTime(now);
            deviceAuthMapper.insert(deviceAuth);

            //封装设备产品授权记录明细
            DeviceAuthDetail deviceAuthDetail = new DeviceAuthDetail();
            deviceAuthDetail.setId(IdWorker.getId());
            deviceAuthDetail.setMerId(merId);
            deviceAuthDetail.setDeviceUniqueId(deviceTiktokInfo.getId());
            deviceAuthDetail.setDeviceId(deviceTiktokInfo.getDeviceId());
            deviceAuthDetail.setDeviceType(DeviceTypeEnum.TIKTOK.getKey());
            deviceAuthDetail.setDeviceTypeId(DeviceTypeEnum.TIKTOK.getId());
            deviceAuthDetail.setProductCode(productCode);
            deviceAuthDetail.setAuthType(DeviceAuthTypeEnum.DAT_FREE.getId().intValue());
            deviceAuthDetail.setQuantity(0); //试用为0
            deviceAuthDetail.setPayTime(now);
            deviceAuthDetail.setPayType(PaymentTypeEnum.PAY_FREE.getId());
            deviceAuthDetail.setTradeno(trandeNo);
            deviceAuthDetail.setRemark("手动试用期授权");
            deviceAuthDetail.setCreateTime(now);
            deviceAuthDetail.setUpdateTime(now);
            deviceAuthDetail.setAmount(0.00);
            deviceAuthDetail.setBeginTime(now);
            deviceAuthDetail.setExpireTime(expired_time);
            //插入授权数据明细
            deviceAuthDetailMapper.insert(deviceAuthDetail);
        }

        //封装机器人授权信息
        List<DeviceInfoTiktokCacheDto.DeviceProductAuth> deviceProductAuthList = new ArrayList<>();
        //查询该机器人的所有产品授权信息
        DeviceAuthQuery deviceAuthQuery = new DeviceAuthQuery();
        deviceAuthQuery.setDeviceId(deviceTiktokInfo.getDeviceId());
        List<DeviceAuth> deviceAuthList = deviceAuthMapper.findByList(deviceAuthQuery);
        if(deviceAuthList != null && deviceAuthList.size() > 0){
            for(DeviceAuth deviceAuth : deviceAuthList){
                //机器人redis缓存信息-产品授权
                DeviceInfoTiktokCacheDto.DeviceProductAuth deviceProductAuth = new DeviceInfoTiktokCacheDto.DeviceProductAuth();
                deviceProductAuth.setAuthType(deviceAuth.getAuthType());
                deviceProductAuth.setExpireTime(deviceAuth.getExpireTime());
                deviceProductAuth.setProductCode(deviceAuth.getProductCode());
                deviceProductAuthList.add(deviceProductAuth);
            }

            //更新移动端redis
            Object object_moblie = redisTemplate.opsForValue().get(String.format(RedisCacheKeyEnum.DEVICE_INFO_TIKTOK.getKey(), deviceTiktokInfo.getId()));
            if(object_moblie != null) { //修改
                DeviceInfoTiktokCacheDto deviceInfoTiktokCacheDto = JSONObject.parseObject(object_moblie.toString(), DeviceInfoTiktokCacheDto.class);
                if(deviceInfoTiktokCacheDto != null){
                    deviceInfoTiktokCacheDto.setDeviceAuths(deviceProductAuthList);
                }
                //更新移动端机器人redis
                redisTemplate.opsForValue().set(String.format(RedisCacheKeyEnum.DEVICE_INFO_TIKTOK.getKey(), deviceTiktokInfo.getId()), Tools.getStrEmpty(JSONObject.toJSONString(deviceInfoTiktokCacheDto)));

            }else{
                DeviceInfoTiktokCacheDto deviceInfoTiktokCacheDto = new DeviceInfoTiktokCacheDto();
                deviceInfoTiktokCacheDto.setMerId(deviceTiktokInfo.getMerId());
                deviceInfoTiktokCacheDto.setDeviceId(deviceTiktokInfo.getDeviceId());
                deviceInfoTiktokCacheDto.setDeviceUniqueId(deviceTiktokInfo.getId());
                deviceInfoTiktokCacheDto.setConfigId(deviceTiktokInfo.getConfigId());
                deviceInfoTiktokCacheDto.setDeviceAuths(deviceProductAuthList);
                deviceInfoTiktokCacheDto.setMsgHandler(1);
                //更新移动端机器人redis
                redisTemplate.opsForValue().set(String.format(RedisCacheKeyEnum.DEVICE_INFO_TIKTOK.getKey(), deviceTiktokInfo.getId()), Tools.getStrEmpty(JSONObject.toJSONString(deviceInfoTiktokCacheDto)));
            }
        }

    }

}
